2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
27 _SCDNotifierRemove(SCDSessionRef session
, CFStringRef key
, int regexOptions
)
29 SCDSessionPrivateRef sessionPrivate
= (SCDSessionPrivateRef
)session
;
31 SCDLog(LOG_DEBUG
, CFSTR("_SCDNotifierRemove:"));
32 SCDLog(LOG_DEBUG
, CFSTR(" key = %@"), key
);
33 SCDLog(LOG_DEBUG
, CFSTR(" regexOptions = %0o"), regexOptions
);
35 if ((session
== NULL
) || (sessionPrivate
->server
== MACH_PORT_NULL
)) {
36 return SCD_NOSESSION
; /* you can't do anything with a closed session */
40 * remove key from this sessions notifier list after checking that
41 * it was previously defined.
43 if (regexOptions
& kSCDRegexKey
) {
44 if (!CFSetContainsValue(sessionPrivate
->reKeys
, key
))
45 return SCD_NOKEY
; /* sorry, key does not exist in notifier list */
46 CFSetRemoveValue(sessionPrivate
->reKeys
, key
); /* remove key from this sessions notifier list */
48 if (!CFSetContainsValue(sessionPrivate
->keys
, key
))
49 return SCD_NOKEY
; /* sorry, key does not exist in notifier list */
50 CFSetRemoveValue(sessionPrivate
->keys
, key
); /* remove key from this sessions notifier list */
53 if (regexOptions
& kSCDRegexKey
) {
54 CFStringRef sessionKey
;
56 CFMutableDictionaryRef newInfo
;
58 CFMutableArrayRef newRKeys
;
60 CFMutableArrayRef newRData
;
63 removeContext context
;
65 sessionKey
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%d"), sessionPrivate
->server
);
67 info
= CFDictionaryGetValue(sessionData
, sessionKey
);
68 newInfo
= CFDictionaryCreateMutableCopy(NULL
, 0, info
);
70 rKeys
= CFDictionaryGetValue(newInfo
, kSCDRegexKeys
);
71 newRKeys
= CFArrayCreateMutableCopy(NULL
, 0, rKeys
);
73 rData
= CFDictionaryGetValue(newInfo
, kSCDRegexData
);
74 newRData
= CFArrayCreateMutableCopy(NULL
, 0, rData
);
76 i
= CFArrayGetFirstIndexOfValue(newRKeys
,
77 CFRangeMake(0, CFArrayGetCount(newRData
)),
79 regexData
= CFArrayGetValueAtIndex(newRData
, i
);
81 context
.session
= sessionPrivate
;
82 context
.preg
= (regex_t
*)CFDataGetBytePtr(regexData
);
83 CFDictionaryApplyFunction(cacheData
,
84 (CFDictionaryApplierFunction
)_removeRegexWatcherByKey
,
87 /* remove the regex key */
88 CFArrayRemoveValueAtIndex(newRKeys
, i
);
89 if (CFArrayGetCount(newRKeys
) > 0) {
90 CFDictionarySetValue(newInfo
, kSCDRegexKeys
, newRKeys
);
92 CFDictionaryRemoveValue(newInfo
, kSCDRegexKeys
);
96 /* ...and the compiled expression */
97 regfree((regex_t
*)CFDataGetBytePtr(regexData
));
98 CFArrayRemoveValueAtIndex(newRData
, i
);
99 if (CFArrayGetCount(newRData
) > 0) {
100 CFDictionarySetValue(newInfo
, kSCDRegexData
, newRData
);
102 CFDictionaryRemoveValue(newInfo
, kSCDRegexData
);
106 /* save the updated session data */
107 CFDictionarySetValue(sessionData
, sessionKey
, newInfo
);
110 CFRelease(sessionKey
);
112 CFNumberRef sessionNum
;
115 * We are watching a specific key. As such, update the
116 * cache to mark our interest in any changes.
119 sessionNum
= CFNumberCreate(NULL
, kCFNumberIntType
, &sessionPrivate
->server
);
120 _removeWatcher(sessionNum
, key
);
121 CFRelease(sessionNum
);
129 _notifyremove(mach_port_t server
,
130 xmlData_t keyRef
, /* raw XML bytes */
131 mach_msg_type_number_t keyLen
,
136 kern_return_t status
;
137 serverSessionRef mySession
= getSession(server
);
138 CFDataRef xmlKey
; /* key (XML serialized) */
139 CFStringRef key
; /* key (un-serialized) */
140 CFStringRef xmlError
;
142 SCDLog(LOG_DEBUG
, CFSTR("Remove notification key for this session."));
143 SCDLog(LOG_DEBUG
, CFSTR(" server = %d"), server
);
145 /* un-serialize the key */
146 xmlKey
= CFDataCreate(NULL
, keyRef
, keyLen
);
147 status
= vm_deallocate(mach_task_self(), (vm_address_t
)keyRef
, keyLen
);
148 if (status
!= KERN_SUCCESS
) {
149 SCDLog(LOG_DEBUG
, CFSTR("vm_deallocate(): %s"), mach_error_string(status
));
150 /* non-fatal???, proceed */
152 key
= CFPropertyListCreateFromXMLData(NULL
,
154 kCFPropertyListImmutable
,
158 SCDLog(LOG_DEBUG
, CFSTR("CFPropertyListCreateFromXMLData() key: %s"), xmlError
);
159 *scd_status
= SCD_FAILED
;
163 *scd_status
= _SCDNotifierRemove(mySession
->session
, key
, regexOptions
);