#include "configd.h"
#include "session.h"
int
__SCDynamicStoreCopyValue(SCDynamicStoreRef store, CFStringRef key, CFPropertyListRef *value)
{
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
CFDictionaryRef dict;
SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreCopyValue:"));
SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" key = %@"), key);
if (!store || (storePrivate->server == MACH_PORT_NULL)) {
return kSCStatusNoStoreSession;
}
dict = CFDictionaryGetValue(storeData, key);
if ((dict == NULL) || (CFDictionaryContainsKey(dict, kSCDData) == FALSE)) {
return kSCStatusNoKey;
}
*value = CFRetain(CFDictionaryGetValue(dict, kSCDData));
SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" value = %@"), *value);
return kSCStatusOK;
}
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
)
{
kern_return_t status;
serverSessionRef mySession = getSession(server);
CFDataRef xmlKey;
CFStringRef key;
CFDataRef xmlData;
CFPropertyListRef value;
CFStringRef xmlError;
SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Get key from configuration database."));
SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
xmlKey = CFDataCreate(NULL, keyRef, keyLen);
status = vm_deallocate(mach_task_self(), (vm_address_t)keyRef, keyLen);
if (status != KERN_SUCCESS) {
SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
}
key = CFPropertyListCreateFromXMLData(NULL,
xmlKey,
kCFPropertyListImmutable,
&xmlError);
CFRelease(xmlKey);
if (!key) {
if (xmlError) {
SCLog(_configd_verbose, LOG_DEBUG,
CFSTR("CFPropertyListCreateFromXMLData() key: %@"),
xmlError);
CFRelease(xmlError);
}
*sc_status = kSCStatusFailed;
return KERN_SUCCESS;
} else if (!isA_CFString(key)) {
*sc_status = kSCStatusInvalidArgument;
return KERN_SUCCESS;
}
*sc_status = __SCDynamicStoreCopyValue(mySession->store, key, &value);
CFRelease(key);
if (*sc_status != kSCStatusOK) {
*dataRef = NULL;
*dataLen = 0;
return KERN_SUCCESS;
}
xmlData = CFPropertyListCreateXMLData(NULL, value);
CFRelease(value);
*dataLen = CFDataGetLength(xmlData);
status = vm_allocate(mach_task_self(), (void *)dataRef, *dataLen, TRUE);
if (status != KERN_SUCCESS) {
SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_allocate(): %s"), mach_error_string(status));
*sc_status = kSCStatusFailed;
CFRelease(xmlData);
*dataRef = NULL;
*dataLen = 0;
return KERN_SUCCESS;
}
bcopy((char *)CFDataGetBytePtr(xmlData), *dataRef, *dataLen);
CFRelease(xmlData);
*newInstance = 1;
return KERN_SUCCESS;
}
typedef struct {
SCDynamicStoreRef store;
CFMutableDictionaryRef dict;
} addSpecific, *addSpecificRef;
static void
addSpecificKey(const void *value, void *context)
{
CFStringRef key = (CFStringRef)value;
addSpecificRef myContextRef = (addSpecificRef)context;
int sc_status;
CFPropertyListRef data;
if (!isA_CFString(key)) {
return;
}
sc_status = __SCDynamicStoreCopyValue(myContextRef->store, key, &data);
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;
}
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)
{
kern_return_t status;
serverSessionRef mySession = getSession(server);
CFArrayRef keys = NULL;
CFArrayRef patterns = NULL;
CFDataRef xmlData;
addSpecific myContext;
SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Get key from configuration database."));
SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
*sc_status = kSCStatusOK;
if (keysRef && (keysLen > 0)) {
CFDataRef xmlKeys;
CFStringRef xmlError;
xmlKeys = CFDataCreate(NULL, keysRef, keysLen);
status = vm_deallocate(mach_task_self(), (vm_address_t)keysRef, keysLen);
if (status != KERN_SUCCESS) {
SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
}
keys = CFPropertyListCreateFromXMLData(NULL,
xmlKeys,
kCFPropertyListImmutable,
&xmlError);
CFRelease(xmlKeys);
if (!keys) {
if (xmlError) {
SCLog(_configd_verbose, LOG_DEBUG,
CFSTR("CFPropertyListCreateFromXMLData() keys: %@"),
xmlError);
CFRelease(xmlError);
}
*sc_status = kSCStatusFailed;
} else if (!isA_CFArray(keys)) {
*sc_status = kSCStatusInvalidArgument;
}
}
if (patternsRef && (patternsLen > 0)) {
CFDataRef xmlPatterns;
CFStringRef xmlError;
xmlPatterns = CFDataCreate(NULL, patternsRef, patternsLen);
status = vm_deallocate(mach_task_self(), (vm_address_t)patternsRef, patternsLen);
if (status != KERN_SUCCESS) {
SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
}
patterns = CFPropertyListCreateFromXMLData(NULL,
xmlPatterns,
kCFPropertyListImmutable,
&xmlError);
CFRelease(xmlPatterns);
if (!patterns) {
if (xmlError) {
SCLog(_configd_verbose, LOG_DEBUG,
CFSTR("CFPropertyListCreateFromXMLData() patterns: %@"),
xmlError);
CFRelease(xmlError);
}
*sc_status = kSCStatusFailed;
} else if (!isA_CFArray(patterns)) {
*sc_status = kSCStatusInvalidArgument;
}
}
if (*sc_status != kSCStatusOK) {
if (keys) CFRelease(keys);
if (patterns) CFRelease(patterns);
*dataRef = NULL;
*dataLen = 0;
return KERN_SUCCESS;
}
myContext.store = mySession->store;
myContext.dict = CFDictionaryCreateMutable(NULL,
0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
if (keys) {
CFArrayApplyFunction(keys,
CFRangeMake(0, CFArrayGetCount(keys)),
addSpecificKey,
&myContext);
CFRelease(keys);
}
if (patterns) {
CFArrayApplyFunction(patterns,
CFRangeMake(0, CFArrayGetCount(patterns)),
addSpecificPattern,
&myContext);
CFRelease(patterns);
}
xmlData = CFPropertyListCreateXMLData(NULL, myContext.dict);
CFRelease(myContext.dict);
*dataLen = CFDataGetLength(xmlData);
status = vm_allocate(mach_task_self(), (void *)dataRef, *dataLen, TRUE);
if (status != KERN_SUCCESS) {
SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_allocate(): %s"), mach_error_string(status));
*sc_status = kSCStatusFailed;
CFRelease(xmlData);
*dataRef = NULL;
*dataLen = 0;
return KERN_SUCCESS;
}
bcopy((char *)CFDataGetBytePtr(xmlData), *dataRef, *dataLen);
CFRelease(xmlData);
return KERN_SUCCESS;
}