#include "configd.h"
#include "session.h"
__private_extern__
int
__SCDynamicStoreCopyValue(SCDynamicStoreRef store, CFStringRef key, CFDataRef *value, Boolean internal)
{
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
CFDictionaryRef dict;
SC_trace("%s : %5d : %@",
internal ? "*copy " : "copy ",
storePrivate->server,
key);
dict = CFDictionaryGetValue(storeData, key);
if ((dict == NULL) || !CFDictionaryContainsKey(dict, kSCDData)) {
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,
audit_token_t audit_token)
{
CFStringRef key = NULL;
CFIndex len;
serverSessionRef mySession;
Boolean ok;
CFDataRef value;
*dataRef = NULL;
*dataLen = 0;
*newInstance = 0;
if (!_SCUnserializeString(&key, NULL, (void *)keyRef, keyLen)) {
*sc_status = kSCStatusFailed;
goto done;
}
if (!isA_CFString(key)) {
*sc_status = kSCStatusInvalidArgument;
goto done;
}
mySession = getSession(server);
if (mySession == NULL) {
mySession = tempSession(server, CFSTR("SCDynamicStoreCopyValue"), audit_token);
if (mySession == NULL) {
*sc_status = kSCStatusNoStoreSession;
goto done;
}
}
*sc_status = __SCDynamicStoreCopyValue(mySession->store, key, &value, FALSE);
if (*sc_status != kSCStatusOK) {
goto done;
}
ok = _SCSerializeData(value, (void **)dataRef, &len);
*dataLen = (mach_msg_type_number_t)len;
CFRelease(value);
if (!ok) {
*sc_status = kSCStatusFailed;
goto done;
}
done :
if (key != NULL) 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;
SC_trace("copy m : %5d : %ld keys, %ld patterns",
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,
audit_token_t audit_token)
{
CFDictionaryRef dict = NULL;
CFArrayRef keys = NULL;
CFIndex len;
serverSessionRef mySession;
Boolean ok;
CFArrayRef patterns = NULL;
*dataRef = NULL;
*dataLen = 0;
*sc_status = kSCStatusOK;
if (keysRef && (keysLen > 0)) {
if (!_SCUnserialize((CFPropertyListRef *)&keys, NULL, (void *)keysRef, keysLen)) {
*sc_status = kSCStatusFailed;
}
}
if (patternsRef && (patternsLen > 0)) {
if (!_SCUnserialize((CFPropertyListRef *)&patterns, NULL, (void *)patternsRef, patternsLen)) {
*sc_status = kSCStatusFailed;
}
}
if (*sc_status != kSCStatusOK) {
goto done;
}
if ((keys != NULL) && !isA_CFArray(keys)) {
*sc_status = kSCStatusInvalidArgument;
goto done;
}
if ((patterns != NULL) && !isA_CFArray(patterns)) {
*sc_status = kSCStatusInvalidArgument;
goto done;
}
mySession = getSession(server);
if (mySession == NULL) {
mySession = tempSession(server, CFSTR("SCDynamicStoreCopyMultiple"), audit_token);
if (mySession == NULL) {
*sc_status = kSCStatusNoStoreSession;
goto done;
}
}
*sc_status = __SCDynamicStoreCopyMultiple(mySession->store, keys, patterns, &dict);
ok = _SCSerialize(dict, NULL, (void **)dataRef, &len);
*dataLen = (mach_msg_type_number_t)len;
CFRelease(dict);
if (!ok) {
*sc_status = kSCStatusFailed;
}
done :
if (keys) CFRelease(keys);
if (patterns) CFRelease(patterns);
return KERN_SUCCESS;
}