#include "configd.h"
#include "session.h"
SCDStatus
_SCDNotifierRemove(SCDSessionRef session, CFStringRef key, int regexOptions)
{
SCDSessionPrivateRef sessionPrivate = (SCDSessionPrivateRef)session;
SCDLog(LOG_DEBUG, CFSTR("_SCDNotifierRemove:"));
SCDLog(LOG_DEBUG, CFSTR(" key = %@"), key);
SCDLog(LOG_DEBUG, CFSTR(" regexOptions = %0o"), regexOptions);
if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
return SCD_NOSESSION;
}
if (regexOptions & kSCDRegexKey) {
if (!CFSetContainsValue(sessionPrivate->reKeys, key))
return SCD_NOKEY;
CFSetRemoveValue(sessionPrivate->reKeys, key);
} else {
if (!CFSetContainsValue(sessionPrivate->keys, key))
return SCD_NOKEY;
CFSetRemoveValue(sessionPrivate->keys, key);
}
if (regexOptions & kSCDRegexKey) {
CFStringRef sessionKey;
CFDictionaryRef info;
CFMutableDictionaryRef newInfo;
CFArrayRef rKeys;
CFMutableArrayRef newRKeys;
CFArrayRef rData;
CFMutableArrayRef newRData;
CFIndex i;
CFDataRef regexData;
removeContext context;
sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), sessionPrivate->server);
info = CFDictionaryGetValue(sessionData, sessionKey);
newInfo = CFDictionaryCreateMutableCopy(NULL, 0, info);
rKeys = CFDictionaryGetValue(newInfo, kSCDRegexKeys);
newRKeys = CFArrayCreateMutableCopy(NULL, 0, rKeys);
rData = CFDictionaryGetValue(newInfo, kSCDRegexData);
newRData = CFArrayCreateMutableCopy(NULL, 0, rData);
i = CFArrayGetFirstIndexOfValue(newRKeys,
CFRangeMake(0, CFArrayGetCount(newRData)),
key);
regexData = CFArrayGetValueAtIndex(newRData, i);
context.session = sessionPrivate;
context.preg = (regex_t *)CFDataGetBytePtr(regexData);
CFDictionaryApplyFunction(cacheData,
(CFDictionaryApplierFunction)_removeRegexWatcherByKey,
&context);
CFArrayRemoveValueAtIndex(newRKeys, i);
if (CFArrayGetCount(newRKeys) > 0) {
CFDictionarySetValue(newInfo, kSCDRegexKeys, newRKeys);
} else {
CFDictionaryRemoveValue(newInfo, kSCDRegexKeys);
}
CFRelease(newRKeys);
regfree((regex_t *)CFDataGetBytePtr(regexData));
CFArrayRemoveValueAtIndex(newRData, i);
if (CFArrayGetCount(newRData) > 0) {
CFDictionarySetValue(newInfo, kSCDRegexData, newRData);
} else {
CFDictionaryRemoveValue(newInfo, kSCDRegexData);
}
CFRelease(newRData);
CFDictionarySetValue(sessionData, sessionKey, newInfo);
CFRelease(newInfo);
CFRelease(sessionKey);
} else {
CFNumberRef sessionNum;
sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &sessionPrivate->server);
_removeWatcher(sessionNum, key);
CFRelease(sessionNum);
}
return SCD_OK;
}
kern_return_t
_notifyremove(mach_port_t server,
xmlData_t keyRef,
mach_msg_type_number_t keyLen,
int regexOptions,
int *scd_status
)
{
kern_return_t status;
serverSessionRef mySession = getSession(server);
CFDataRef xmlKey;
CFStringRef key;
CFStringRef xmlError;
SCDLog(LOG_DEBUG, CFSTR("Remove notification key for this session."));
SCDLog(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) {
SCDLog(LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
}
key = CFPropertyListCreateFromXMLData(NULL,
xmlKey,
kCFPropertyListImmutable,
&xmlError);
CFRelease(xmlKey);
if (xmlError) {
SCDLog(LOG_DEBUG, CFSTR("CFPropertyListCreateFromXMLData() key: %s"), xmlError);
*scd_status = SCD_FAILED;
return KERN_SUCCESS;
}
*scd_status = _SCDNotifierRemove(mySession->session, key, regexOptions);
CFRelease(key);
return KERN_SUCCESS;
}