/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* @APPLE_LICENSE_HEADER_END@
*/
+/*
+ * Modification History
+ *
+ * June 1, 2001 Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * March 24, 2000 Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
#include "configd.h"
#include "session.h"
-SCDStatus
-_SCDList(SCDSessionRef session, CFStringRef key, int regexOptions, CFArrayRef *subKeys)
+int
+__SCDynamicStoreCopyKeyList(SCDynamicStoreRef store, CFStringRef key, Boolean isRegex, CFArrayRef *subKeys)
{
- SCDSessionPrivateRef sessionPrivate = (SCDSessionPrivateRef)session;
- CFIndex cacheCnt;
- void **cacheKeys;
- void **cacheValues;
- CFMutableArrayRef keyArray;
- int i;
- CFStringRef cacheStr;
- CFDictionaryRef cacheValue;
- int regexStrLen;
- char *regexStr = NULL;
- regex_t preg;
- int reError;
- char reErrBuf[256];
- int reErrStrLen;
-
- SCDLog(LOG_DEBUG, CFSTR("_SCDList:"));
- SCDLog(LOG_DEBUG, CFSTR(" key = %@"), key);
- SCDLog(LOG_DEBUG, CFSTR(" regexOptions = %0o"), regexOptions);
-
- if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
- return SCD_NOSESSION;
+ SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
+ CFIndex storeCnt;
+ const void **storeKeys;
+ const void **storeValues;
+ CFMutableArrayRef keyArray;
+ int i;
+ CFStringRef storeStr;
+ CFDictionaryRef storeValue;
+ int regexBufLen;
+ char *regexBuf = NULL;
+ regex_t preg;
+ int reError;
+ char reErrBuf[256];
+ int reErrStrLen;
+
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreCopyKeyList:"));
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" key = %@"), key);
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" isRegex = %s"), isRegex ? "TRUE" : "FALSE");
+
+ if (!store || (storePrivate->server == MACH_PORT_NULL)) {
+ return kSCStatusNoStoreSession; /* you must have an open session to play */
}
- cacheCnt = CFDictionaryGetCount(cacheData);
- keyArray = CFArrayCreateMutable(NULL, cacheCnt, &kCFTypeArrayCallBacks);
+ storeCnt = CFDictionaryGetCount(storeData);
+ keyArray = CFArrayCreateMutable(NULL, storeCnt, &kCFTypeArrayCallBacks);
+
+ if (isRegex) {
+ UniChar ch_s = 0;
+ UniChar ch_e = 0;
+ Boolean ok;
+ CFIndex regexLen;
+ CFMutableStringRef regexStr;
+
+ regexStr = CFStringCreateMutableCopy(NULL, 0, key);
+ regexLen = CFStringGetLength(regexStr);
+ if (regexLen > 0) {
+ ch_s = CFStringGetCharacterAtIndex(regexStr, 0);
+ ch_e = CFStringGetCharacterAtIndex(regexStr, regexLen - 1);
+ }
+ if ((regexLen == 0) || ((ch_s != (UniChar)'^') && (ch_e != (UniChar)'$'))) {
+ /* if regex pattern is not already bounded */
+ CFStringInsert(regexStr, 0, CFSTR("^"));
+ CFStringAppend(regexStr, CFSTR("$"));
+ }
- if (regexOptions & kSCDRegexKey) {
/*
* compile the provided regular expression using the
- * provided regexOptions (passing only those flags
- * which would make sense).
+ * provided isRegex.
*/
- regexStrLen = CFStringGetLength(key) + 1;
- regexStr = CFAllocatorAllocate(NULL, regexStrLen, 0);
- if (!CFStringGetCString(key,
- regexStr,
- regexStrLen,
- kCFStringEncodingMacRoman)) {
- SCDLog(LOG_DEBUG, CFSTR("CFStringGetCString() key: could not convert to regex string"));
- CFAllocatorDeallocate(NULL, regexStr);
- return SCD_FAILED;
+ regexBufLen = CFStringGetLength(regexStr) + 1;
+ regexBuf = CFAllocatorAllocate(NULL, regexBufLen, 0);
+ ok = CFStringGetCString(regexStr, regexBuf, regexBufLen, kCFStringEncodingMacRoman);
+ CFRelease(regexStr);
+ if (!ok) {
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR("CFStringGetCString() key: could not convert to regex string"));
+ CFAllocatorDeallocate(NULL, regexBuf);
+ return kSCStatusFailed;
}
- reError = regcomp(&preg, regexStr, REG_EXTENDED);
+ reError = regcomp(&preg, regexBuf, REG_EXTENDED);
if (reError != 0) {
reErrStrLen = regerror(reError, &preg, reErrBuf, sizeof(reErrBuf));
- cacheStr = CFStringCreateWithCString(NULL, reErrBuf, kCFStringEncodingMacRoman);
- CFArrayAppendValue(keyArray, cacheStr);
- CFRelease(cacheStr);
+ storeStr = CFStringCreateWithCString(NULL, reErrBuf, kCFStringEncodingMacRoman);
+ CFArrayAppendValue(keyArray, storeStr);
+ CFRelease(storeStr);
*subKeys = CFArrayCreateCopy(NULL, keyArray);
CFRelease(keyArray);
- CFAllocatorDeallocate(NULL, regexStr);
- return SCD_FAILED;
+ CFAllocatorDeallocate(NULL, regexBuf);
+ return kSCStatusFailed;
}
}
- cacheKeys = CFAllocatorAllocate(NULL, cacheCnt * sizeof(CFStringRef), 0);
- cacheValues = CFAllocatorAllocate(NULL, cacheCnt * sizeof(CFStringRef), 0);
- CFDictionaryGetKeysAndValues(cacheData, cacheKeys, cacheValues);
- for (i=0; i<cacheCnt; i++) {
- cacheStr = (CFStringRef)cacheKeys[i];
- cacheValue = (CFDictionaryRef)cacheValues[i];
- if (regexOptions & kSCDRegexKey) {
- /*
- * only return those keys which match the regular
- * expression specified in the provided key.
- */
-
- int cacheKeyLen = CFStringGetLength(cacheStr) + 1;
- char *cacheKey = CFAllocatorAllocate(NULL, cacheKeyLen, 0);
-
- if (!CFStringGetCString(cacheStr,
- cacheKey,
- cacheKeyLen,
- kCFStringEncodingMacRoman)) {
- SCDLog(LOG_DEBUG, CFSTR("CFStringGetCString: could not convert cache key to C string"));
- CFAllocatorDeallocate(NULL, cacheKey);
- continue;
- }
-
- reError = regexec(&preg,
- cacheKey,
- 0,
- NULL,
- 0);
- switch (reError) {
- case 0 :
- /* we've got a match */
- if (CFDictionaryContainsKey(cacheValue, kSCDData))
- CFArrayAppendValue(keyArray, cacheStr);
- break;
- case REG_NOMATCH :
- /* no match */
- break;
- default :
- reErrStrLen = regerror(reError,
- &preg,
- reErrBuf,
- sizeof(reErrBuf));
- SCDLog(LOG_DEBUG, CFSTR("regexec(): %s"), reErrBuf);
- break;
- }
- CFAllocatorDeallocate(NULL, cacheKey);
- } else {
- /*
- * only return those keys which are prefixed by the
- * provided key string and have data.
- */
- if (((CFStringGetLength(key) == 0) || CFStringHasPrefix(cacheStr, key)) &&
- CFDictionaryContainsKey(cacheValue, kSCDData)) {
- CFArrayAppendValue(keyArray, cacheStr);
+ if (storeCnt > 0) {
+ storeKeys = CFAllocatorAllocate(NULL, storeCnt * sizeof(CFStringRef), 0);
+ storeValues = CFAllocatorAllocate(NULL, storeCnt * sizeof(CFStringRef), 0);
+ CFDictionaryGetKeysAndValues(storeData, storeKeys, storeValues);
+ for (i=0; i<storeCnt; i++) {
+ storeStr = (CFStringRef)storeKeys[i];
+ storeValue = (CFDictionaryRef)storeValues[i];
+ if (isRegex) {
+ /*
+ * only return those keys which match the regular
+ * expression specified in the provided key.
+ */
+
+ int storeKeyLen = CFStringGetLength(storeStr) + 1;
+ char *storeKey = CFAllocatorAllocate(NULL, storeKeyLen, 0);
+
+ if (!CFStringGetCString(storeStr,
+ storeKey,
+ storeKeyLen,
+ kCFStringEncodingMacRoman)) {
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR("CFStringGetCString: could not convert store key to C string"));
+ CFAllocatorDeallocate(NULL, storeKey);
+ continue;
+ }
+
+ reError = regexec(&preg,
+ storeKey,
+ 0,
+ NULL,
+ 0);
+ switch (reError) {
+ case 0 :
+ /* we've got a match */
+ if (CFDictionaryContainsKey(storeValue, kSCDData))
+ CFArrayAppendValue(keyArray, storeStr);
+ break;
+ case REG_NOMATCH :
+ /* no match */
+ break;
+ default :
+ reErrStrLen = regerror(reError,
+ &preg,
+ reErrBuf,
+ sizeof(reErrBuf));
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR("regexec(): %s"), reErrBuf);
+ break;
+ }
+ CFAllocatorDeallocate(NULL, storeKey);
+ } else {
+ /*
+ * only return those keys which are prefixed by the
+ * provided key string and have data.
+ */
+ if (((CFStringGetLength(key) == 0) || CFStringHasPrefix(storeStr, key)) &&
+ CFDictionaryContainsKey(storeValue, kSCDData)) {
+ CFArrayAppendValue(keyArray, storeStr);
+ }
}
}
+ CFAllocatorDeallocate(NULL, storeKeys);
+ CFAllocatorDeallocate(NULL, storeValues);
}
- CFAllocatorDeallocate(NULL, cacheKeys);
- CFAllocatorDeallocate(NULL, cacheValues);
- if (regexOptions & kSCDRegexKey) {
+ if (isRegex) {
regfree(&preg);
+ CFAllocatorDeallocate(NULL, regexBuf);
}
*subKeys = keyArray;
- if (regexOptions & kSCDRegexKey) {
- CFAllocatorDeallocate(NULL, regexStr);
- }
-
- return SCD_OK;
+ return kSCStatusOK;
}
_configlist(mach_port_t server,
xmlData_t keyRef, /* raw XML bytes */
mach_msg_type_number_t keyLen,
- int regexOptions,
+ int isRegex,
xmlDataOut_t *listRef, /* raw XML bytes */
mach_msg_type_number_t *listLen,
- int *scd_status
+ int *sc_status
)
{
- kern_return_t status;
- serverSessionRef mySession = getSession(server);
- CFDataRef xmlKey; /* key (XML serialized) */
CFStringRef key; /* key (un-serialized) */
+ serverSessionRef mySession = getSession(server);
+ Boolean ok;
CFArrayRef subKeys; /* array of CFStringRef's */
- CFDataRef xmlList; /* list (XML serialized) */
- CFStringRef xmlError;
- SCDLog(LOG_DEBUG, CFSTR("List keys in configuration database."));
- SCDLog(LOG_DEBUG, CFSTR(" server = %d"), server);
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR("List keys in configuration database."));
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
+
+ *listRef = NULL;
+ *listLen = 0;
/* un-serialize the key */
- xmlKey = CFDataCreate(NULL, keyRef, keyLen);
- status = vm_deallocate(mach_task_self(), (vm_address_t)keyRef, keyLen);
- if (status != KERN_SUCCESS) {
- SCDLog(LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
- /* non-fatal???, proceed */
+ if (!_SCUnserialize((CFPropertyListRef *)&key, (void *)keyRef, keyLen)) {
+ *sc_status = kSCStatusFailed;
+ return KERN_SUCCESS;
}
- key = CFPropertyListCreateFromXMLData(NULL,
- xmlKey,
- kCFPropertyListImmutable,
- &xmlError);
- CFRelease(xmlKey);
- if (xmlError) {
- SCDLog(LOG_DEBUG, CFSTR("CFPropertyListCreateFromXMLData() key: %s"), xmlError);
- *scd_status = SCD_FAILED;
+
+ if (!isA_CFString(key)) {
+ CFRelease(key);
+ *sc_status = kSCStatusInvalidArgument;
return KERN_SUCCESS;
}
- *scd_status = _SCDList(mySession->session, key, regexOptions, &subKeys);
+ *sc_status = __SCDynamicStoreCopyKeyList(mySession->store, key, isRegex, &subKeys);
CFRelease(key);
- if (*scd_status != SCD_OK) {
- *listRef = NULL;
- *listLen = 0;
+ if (*sc_status != kSCStatusOK) {
return KERN_SUCCESS;
}
- /*
- * serialize the array, copy it into an allocated buffer which will be
- * released when it is returned as part of a Mach message.
- */
- xmlList = CFPropertyListCreateXMLData(NULL, subKeys);
+ /* serialize the list of keys */
+ ok = _SCSerialize(subKeys, NULL, (void **)listRef, (CFIndex *)listLen);
CFRelease(subKeys);
- *listLen = CFDataGetLength(xmlList);
- status = vm_allocate(mach_task_self(), (void *)listRef, *listLen, TRUE);
- if (status != KERN_SUCCESS) {
- SCDLog(LOG_DEBUG, CFSTR("vm_allocate(): %s"), mach_error_string(status));
- *scd_status = SCD_FAILED;
- CFRelease(xmlList);
- *listRef = NULL;
- *listLen = 0;
+ if (!ok) {
+ *sc_status = kSCStatusFailed;
return KERN_SUCCESS;
}
- bcopy((char *)CFDataGetBytePtr(xmlList), *listRef, *listLen);
- CFRelease(xmlList);
return KERN_SUCCESS;
}