#include "SCDynamicStoreInternal.h"
#include "config.h"
CFDictionaryRef
SCDynamicStoreCopyMultiple(SCDynamicStoreRef store,
CFArrayRef keys,
CFArrayRef patterns)
{
SCDynamicStorePrivateRef storePrivate;
kern_return_t status;
CFDataRef xmlKeys = NULL;
xmlData_t myKeysRef = NULL;
CFIndex myKeysLen = 0;
CFDataRef xmlPatterns = NULL;
xmlData_t myPatternsRef = NULL;
CFIndex myPatternsLen = 0;
xmlDataOut_t xmlDictRef = NULL;
mach_msg_type_number_t xmlDictLen = 0;
CFDictionaryRef dict = NULL;
CFDictionaryRef expDict = NULL;
int sc_status;
if (store == NULL) {
store = __SCDynamicStoreNullSession();
if (store == NULL) {
_SCErrorSet(kSCStatusNoStoreSession);
return NULL;
}
}
storePrivate = (SCDynamicStorePrivateRef)store;
if (storePrivate->server == MACH_PORT_NULL) {
_SCErrorSet(kSCStatusNoStoreServer);
return NULL;
}
if (keys != NULL) {
if (!_SCSerialize(keys, &xmlKeys, (void **)&myKeysRef, &myKeysLen)) {
_SCErrorSet(kSCStatusFailed);
return NULL;
}
}
if (patterns != NULL) {
if (!_SCSerialize(patterns, &xmlPatterns, (void **)&myPatternsRef, &myPatternsLen)) {
if (xmlKeys != NULL) CFRelease(xmlKeys);
_SCErrorSet(kSCStatusFailed);
return NULL;
}
}
retry :
status = configget_m(storePrivate->server,
myKeysRef,
(mach_msg_type_number_t)myKeysLen,
myPatternsRef,
(mach_msg_type_number_t)myPatternsLen,
&xmlDictRef,
&xmlDictLen,
(int *)&sc_status);
if (__SCDynamicStoreCheckRetryAndHandleError(store,
status,
&sc_status,
"SCDynamicStoreCopyMultiple configget_m()")) {
goto retry;
}
if (sc_status != kSCStatusOK) {
if (xmlDictRef != NULL) {
(void) vm_deallocate(mach_task_self(), (vm_address_t)xmlDictRef, xmlDictLen);
}
_SCErrorSet(sc_status);
goto done;
}
if (!_SCUnserialize((CFPropertyListRef *)&dict, NULL, xmlDictRef, xmlDictLen)) {
_SCErrorSet(kSCStatusFailed);
goto done;
}
expDict = _SCUnserializeMultiple(dict);
CFRelease(dict);
done:
if (xmlKeys != NULL) CFRelease(xmlKeys);
if (xmlPatterns != NULL) CFRelease(xmlPatterns);
return expDict;
}
CFPropertyListRef
SCDynamicStoreCopyValue(SCDynamicStoreRef store, CFStringRef key)
{
SCDynamicStorePrivateRef storePrivate;
kern_return_t status;
CFDataRef utfKey;
xmlData_t myKeyRef;
CFIndex myKeyLen;
xmlDataOut_t xmlDataRef = NULL;
mach_msg_type_number_t xmlDataLen = 0;
CFPropertyListRef data;
int newInstance;
int sc_status;
if (store == NULL) {
store = __SCDynamicStoreNullSession();
if (store == NULL) {
_SCErrorSet(kSCStatusNoStoreSession);
return NULL;
}
}
storePrivate = (SCDynamicStorePrivateRef)store;
if (storePrivate->server == MACH_PORT_NULL) {
_SCErrorSet(kSCStatusNoStoreServer);
return NULL;
}
if (storePrivate->cache_active) {
if ((storePrivate->cached_set != NULL) &&
CFDictionaryGetValueIfPresent(storePrivate->cached_set, key, (const void **)&data)) {
return (CFRetain(data));
}
if ((storePrivate->cached_removals != NULL) &&
CFArrayContainsValue(storePrivate->cached_removals,
CFRangeMake(0, CFArrayGetCount(storePrivate->cached_removals)),
key)) {
_SCErrorSet(kSCStatusNoKey);
return NULL;
}
if ((storePrivate->cached_keys != NULL) &&
CFDictionaryGetValueIfPresent(storePrivate->cached_keys, key, (const void **)&data)) {
return (CFRetain(data));
}
}
if (!_SCSerializeString(key, &utfKey, (void **)&myKeyRef, &myKeyLen)) {
_SCErrorSet(kSCStatusFailed);
return NULL;
}
retry :
status = configget(storePrivate->server,
myKeyRef,
(mach_msg_type_number_t)myKeyLen,
&xmlDataRef,
&xmlDataLen,
&newInstance,
(int *)&sc_status);
if (__SCDynamicStoreCheckRetryAndHandleError(store,
status,
&sc_status,
"SCDynamicStoreCopyValue configget()")) {
goto retry;
}
CFRelease(utfKey);
if (sc_status != kSCStatusOK) {
if (xmlDataRef != NULL) {
(void) vm_deallocate(mach_task_self(), (vm_address_t)xmlDataRef, xmlDataLen);
}
_SCErrorSet(sc_status);
return NULL;
}
if (!_SCUnserialize(&data, NULL, xmlDataRef, xmlDataLen)) {
_SCErrorSet(kSCStatusFailed);
return NULL;
}
if (storePrivate->cache_active && (data != NULL)) {
if (storePrivate->cached_keys == NULL) {
storePrivate->cached_keys = CFDictionaryCreateMutable(NULL,
0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
}
CFDictionarySetValue(storePrivate->cached_keys, key, data);
}
return data;
}