]> git.saurik.com Git - apple/configd.git/blob - configd.tproj/_notifyremove.c
configd-24.1.tar.gz
[apple/configd.git] / configd.tproj / _notifyremove.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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.
11 *
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
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23 #include "configd.h"
24 #include "session.h"
25
26 SCDStatus
27 _SCDNotifierRemove(SCDSessionRef session, CFStringRef key, int regexOptions)
28 {
29 SCDSessionPrivateRef sessionPrivate = (SCDSessionPrivateRef)session;
30
31 SCDLog(LOG_DEBUG, CFSTR("_SCDNotifierRemove:"));
32 SCDLog(LOG_DEBUG, CFSTR(" key = %@"), key);
33 SCDLog(LOG_DEBUG, CFSTR(" regexOptions = %0o"), regexOptions);
34
35 if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
36 return SCD_NOSESSION; /* you can't do anything with a closed session */
37 }
38
39 /*
40 * remove key from this sessions notifier list after checking that
41 * it was previously defined.
42 */
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 */
47 } else {
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 */
51 }
52
53 if (regexOptions & kSCDRegexKey) {
54 CFStringRef sessionKey;
55 CFDictionaryRef info;
56 CFMutableDictionaryRef newInfo;
57 CFArrayRef rKeys;
58 CFMutableArrayRef newRKeys;
59 CFArrayRef rData;
60 CFMutableArrayRef newRData;
61 CFIndex i;
62 CFDataRef regexData;
63 removeContext context;
64
65 sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), sessionPrivate->server);
66
67 info = CFDictionaryGetValue(sessionData, sessionKey);
68 newInfo = CFDictionaryCreateMutableCopy(NULL, 0, info);
69
70 rKeys = CFDictionaryGetValue(newInfo, kSCDRegexKeys);
71 newRKeys = CFArrayCreateMutableCopy(NULL, 0, rKeys);
72
73 rData = CFDictionaryGetValue(newInfo, kSCDRegexData);
74 newRData = CFArrayCreateMutableCopy(NULL, 0, rData);
75
76 i = CFArrayGetFirstIndexOfValue(newRKeys,
77 CFRangeMake(0, CFArrayGetCount(newRData)),
78 key);
79 regexData = CFArrayGetValueAtIndex(newRData, i);
80
81 context.session = sessionPrivate;
82 context.preg = (regex_t *)CFDataGetBytePtr(regexData);
83 CFDictionaryApplyFunction(cacheData,
84 (CFDictionaryApplierFunction)_removeRegexWatcherByKey,
85 &context);
86
87 /* remove the regex key */
88 CFArrayRemoveValueAtIndex(newRKeys, i);
89 if (CFArrayGetCount(newRKeys) > 0) {
90 CFDictionarySetValue(newInfo, kSCDRegexKeys, newRKeys);
91 } else {
92 CFDictionaryRemoveValue(newInfo, kSCDRegexKeys);
93 }
94 CFRelease(newRKeys);
95
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);
101 } else {
102 CFDictionaryRemoveValue(newInfo, kSCDRegexData);
103 }
104 CFRelease(newRData);
105
106 /* save the updated session data */
107 CFDictionarySetValue(sessionData, sessionKey, newInfo);
108 CFRelease(newInfo);
109
110 CFRelease(sessionKey);
111 } else {
112 CFNumberRef sessionNum;
113
114 /*
115 * We are watching a specific key. As such, update the
116 * cache to mark our interest in any changes.
117 */
118
119 sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &sessionPrivate->server);
120 _removeWatcher(sessionNum, key);
121 CFRelease(sessionNum);
122 }
123
124 return SCD_OK;
125 }
126
127
128 kern_return_t
129 _notifyremove(mach_port_t server,
130 xmlData_t keyRef, /* raw XML bytes */
131 mach_msg_type_number_t keyLen,
132 int regexOptions,
133 int *scd_status
134 )
135 {
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;
141
142 SCDLog(LOG_DEBUG, CFSTR("Remove notification key for this session."));
143 SCDLog(LOG_DEBUG, CFSTR(" server = %d"), server);
144
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 */
151 }
152 key = CFPropertyListCreateFromXMLData(NULL,
153 xmlKey,
154 kCFPropertyListImmutable,
155 &xmlError);
156 CFRelease(xmlKey);
157 if (xmlError) {
158 SCDLog(LOG_DEBUG, CFSTR("CFPropertyListCreateFromXMLData() key: %s"), xmlError);
159 *scd_status = SCD_FAILED;
160 return KERN_SUCCESS;
161 }
162
163 *scd_status = _SCDNotifierRemove(mySession->session, key, regexOptions);
164 CFRelease(key);
165
166 return KERN_SUCCESS;
167 }
168