#include "configd.h"
#include "session.h"
__private_extern__
int
__SCDynamicStoreCopyValue(SCDynamicStoreRef store, CFStringRef key, CFDataRef *value, Boolean internal)
{
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
CFDictionaryRef dict;
if (!store || (storePrivate->server == MACH_PORT_NULL)) {
return kSCStatusNoStoreSession;
}
if (_configd_trace) {
SCTrace(TRUE, _configd_trace,
CFSTR("%s : %5d : %@\n"),
internal ? "*copy " : "copy ",
storePrivate->server,
key);
}
dict = CFDictionaryGetValue(storeData, key);
if ((dict == NULL) || (CFDictionaryContainsKey(dict, kSCDData) == FALSE)) {
return kSCStatusNoKey;
}
*value = CFRetain(CFDictionaryGetValue(dict, kSCDData));
return kSCStatusOK;
}
__private_extern__
kern_return_t
_configget(mach_port_t server,
xmlData_t keyRef,
mach_msg_type_number_t keyLen,
xmlDataOut_t *dataRef,
mach_msg_type_number_t *dataLen,
int *newInstance,
int *sc_status
)
{
CFStringRef key = NULL;
serverSessionRef mySession = getSession(server);
Boolean ok;
CFDataRef value;
*dataRef = NULL;
*dataLen = 0;
if (!_SCUnserializeString(&key, NULL, (void *)keyRef, keyLen)) {
*sc_status = kSCStatusFailed;
goto done;
}
if (!isA_CFString(key)) {
*sc_status = kSCStatusInvalidArgument;
goto done;
}
if (!mySession) {
*sc_status = kSCStatusNoStoreSession;
goto done;
}
*sc_status = __SCDynamicStoreCopyValue(mySession->store, key, &value, FALSE);
if (*sc_status != kSCStatusOK) {
goto done;
}
ok = _SCSerializeData(value, (void **)dataRef, (CFIndex *)dataLen);
CFRelease(value);
if (!ok) {
*sc_status = kSCStatusFailed;
goto done;
}
*newInstance = 1;
done :
if (key) CFRelease(key);
return KERN_SUCCESS;
}
typedef struct {
SCDynamicStoreRef store;
CFMutableDictionaryRef dict;
} addSpecific, *addSpecificRef;
static void
addSpecificKey(const void *value, void *context)
{
CFDataRef data;
CFStringRef key = (CFStringRef)value;
addSpecificRef myContextRef = (addSpecificRef)context;
int sc_status;
if (!isA_CFString(key)) {
return;
}
sc_status = __SCDynamicStoreCopyValue(myContextRef->store, key, &data, TRUE);
if (sc_status == kSCStatusOK) {
CFDictionaryAddValue(myContextRef->dict, key, data);
CFRelease(data);
}
return;
}
static void
addSpecificPattern(const void *value, void *context)
{
CFStringRef pattern = (CFStringRef)value;
addSpecificRef myContextRef = (addSpecificRef)context;
int sc_status;
CFArrayRef keys;
if (!isA_CFString(pattern)) {
return;
}
sc_status = __SCDynamicStoreCopyKeyList(myContextRef->store, pattern, TRUE, &keys);
if (sc_status == kSCStatusOK) {
CFArrayApplyFunction(keys,
CFRangeMake(0, CFArrayGetCount(keys)),
addSpecificKey,
context);
CFRelease(keys);
}
return;
}
__private_extern__
int
__SCDynamicStoreCopyMultiple(SCDynamicStoreRef store, CFArrayRef keys, CFArrayRef patterns, CFDictionaryRef *values)
{
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
addSpecific myContext;
if (!store || (storePrivate->server == MACH_PORT_NULL)) {
return kSCStatusNoStoreSession;
}
if (_configd_trace) {
SCTrace(TRUE, _configd_trace,
CFSTR("copy m : %5d : %d keys, %d patterns\n"),
storePrivate->server,
keys ? CFArrayGetCount(keys) : 0,
patterns ? CFArrayGetCount(patterns) : 0);
}
myContext.store = store;
myContext.dict = CFDictionaryCreateMutable(NULL,
0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
if (keys) {
CFArrayApplyFunction(keys,
CFRangeMake(0, CFArrayGetCount(keys)),
addSpecificKey,
&myContext);
}
if (patterns) {
CFArrayApplyFunction(patterns,
CFRangeMake(0, CFArrayGetCount(patterns)),
addSpecificPattern,
&myContext);
}
*values = myContext.dict;
return kSCStatusOK;
}
__private_extern__
kern_return_t
_configget_m(mach_port_t server,
xmlData_t keysRef,
mach_msg_type_number_t keysLen,
xmlData_t patternsRef,
mach_msg_type_number_t patternsLen,
xmlDataOut_t *dataRef,
mach_msg_type_number_t *dataLen,
int *sc_status)
{
CFDictionaryRef dict = NULL;
CFArrayRef keys = NULL;
serverSessionRef mySession = getSession(server);
Boolean ok;
CFArrayRef patterns = NULL;
*dataRef = NULL;
*dataLen = 0;
if (keysRef && (keysLen > 0)) {
if (!_SCUnserialize((CFPropertyListRef *)&keys, NULL, (void *)keysRef, keysLen)) {
*sc_status = kSCStatusFailed;
goto done;
}
if (!isA_CFArray(keys)) {
*sc_status = kSCStatusInvalidArgument;
goto done;
}
}
if (patternsRef && (patternsLen > 0)) {
if (!_SCUnserialize((CFPropertyListRef *)&patterns, NULL, (void *)patternsRef, patternsLen)) {
*sc_status = kSCStatusFailed;
goto done;
}
if (!isA_CFArray(patterns)) {
*sc_status = kSCStatusInvalidArgument;
goto done;
}
}
if (!mySession) {
*sc_status = kSCStatusNoStoreSession;
goto done;
}
*sc_status = __SCDynamicStoreCopyMultiple(mySession->store, keys, patterns, &dict);
ok = _SCSerialize(dict, NULL, (void **)dataRef, (CFIndex *)dataLen);
CFRelease(dict);
if (!ok) {
*sc_status = kSCStatusFailed;
}
done :
if (keys) CFRelease(keys);
if (patterns) CFRelease(patterns);
return KERN_SUCCESS;
}