]> git.saurik.com Git - apple/configd.git/blob - configd.tproj/_configclose.c
configd-24.tar.gz
[apple/configd.git] / configd.tproj / _configclose.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 <unistd.h>
24
25 #include "configd.h"
26 #include "session.h"
27
28 static boolean_t
29 isMySessionKey(CFStringRef sessionKey, CFStringRef key)
30 {
31 CFDictionaryRef dict;
32 CFStringRef cacheSessionKey;
33
34 dict = CFDictionaryGetValue(cacheData, key);
35 if (!dict) {
36 /* if key no longer exists */
37 return FALSE;
38 }
39
40 cacheSessionKey = CFDictionaryGetValue(dict, kSCDSession);
41 if (!cacheSessionKey) {
42 /* if this is not a session key */
43 return FALSE;
44 }
45
46 if (!CFEqual(sessionKey, cacheSessionKey)) {
47 /* if this is not "my" session key */
48 return FALSE;
49 }
50
51 return TRUE;
52 }
53
54
55 SCDStatus
56 _SCDClose(SCDSessionRef *session)
57 {
58 SCDSessionPrivateRef sessionPrivate = (SCDSessionPrivateRef)*session;
59 CFIndex keyCnt;
60 CFStringRef sessionKey;
61 CFDictionaryRef dict;
62 CFArrayRef keys;
63 serverSessionRef mySession;
64
65 SCDLog(LOG_DEBUG, CFSTR("_SCDClose:"));
66
67 if ((*session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
68 return SCD_NOSESSION;
69 }
70
71 /* Remove notification keys */
72 if ((keyCnt = CFSetGetCount(sessionPrivate->keys)) > 0) {
73 void **watchedKeys;
74 CFArrayRef keysToRemove;
75 CFIndex i;
76
77 watchedKeys = CFAllocatorAllocate(NULL, keyCnt * sizeof(CFStringRef), 0);
78 CFSetGetValues(sessionPrivate->keys, watchedKeys);
79 keysToRemove = CFArrayCreate(NULL, watchedKeys, keyCnt, &kCFTypeArrayCallBacks);
80 CFAllocatorDeallocate(NULL, watchedKeys);
81 for (i=0; i<keyCnt; i++) {
82 (void) _SCDNotifierRemove(*session,
83 CFArrayGetValueAtIndex(keysToRemove, i),
84 0);
85 }
86 CFRelease(keysToRemove);
87 }
88
89 /* Remove regex notification keys */
90 if ((keyCnt = CFSetGetCount(sessionPrivate->reKeys)) > 0) {
91 void **watchedKeys;
92 CFArrayRef keysToRemove;
93 CFIndex i;
94
95 watchedKeys = CFAllocatorAllocate(NULL, keyCnt * sizeof(CFStringRef), 0);
96 CFSetGetValues(sessionPrivate->reKeys, watchedKeys);
97 keysToRemove = CFArrayCreate(NULL, watchedKeys, keyCnt, &kCFTypeArrayCallBacks);
98 CFAllocatorDeallocate(NULL, watchedKeys);
99 for (i=0; i<keyCnt; i++) {
100 (void) _SCDNotifierRemove(*session,
101 CFArrayGetValueAtIndex(keysToRemove, i),
102 kSCDRegexKey);
103 }
104 CFRelease(keysToRemove);
105 }
106
107 /* Remove/cancel any outstanding notification requests. */
108 (void) _SCDNotifierCancel(*session);
109
110 /* Remove any session keys */
111 sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), sessionPrivate->server);
112 dict = CFDictionaryGetValue(sessionData, sessionKey);
113 keys = CFDictionaryGetValue(dict, kSCDSessionKeys);
114 if (keys && ((keyCnt = CFArrayGetCount(keys)) > 0)) {
115 boolean_t wasLocked;
116 CFIndex i;
117
118 /*
119 * if necessary, claim a lock to ensure that we inform
120 * any processes that a session key was removed.
121 */
122 wasLocked = SCDOptionGet(NULL, kSCDOptionIsLocked);
123 if (!wasLocked) {
124 (void) _SCDLock(*session);
125 }
126
127 /* remove keys from "locked" cache" */
128 for (i=0; i<keyCnt; i++) {
129 if (isMySessionKey(sessionKey, CFArrayGetValueAtIndex(keys, i)))
130 (void) _SCDRemove(*session, CFArrayGetValueAtIndex(keys, i));
131 }
132
133 if (wasLocked) {
134 /* remove keys from "unlocked" cache" */
135 _swapLockedCacheData();
136 for (i=0; i<keyCnt; i++) {
137 if (isMySessionKey(sessionKey, CFArrayGetValueAtIndex(keys, i)))
138 (void) _SCDRemove(*session, CFArrayGetValueAtIndex(keys, i));
139 }
140 _swapLockedCacheData();
141 }
142
143 /*
144 * Note: everyone who calls _SCDClose() ends up
145 * removing this sessions dictionary. As
146 * such, we don't need to worry about
147 * the session keys.
148 */
149 }
150 CFRelease(sessionKey);
151
152 /* release the lock */
153 if (SCDOptionGet(*session, kSCDOptionIsLocked)) {
154 (void) _SCDUnlock(*session);
155 }
156
157 /*
158 * Invalidate the server port (for this client) which will result
159 * in the removal of any associated run loop sources.
160 */
161 mySession = getSession(sessionPrivate->server);
162 if (mySession->serverRunLoopSource) {
163 CFRunLoopRemoveSource(CFRunLoopGetCurrent(),
164 mySession->serverRunLoopSource,
165 kCFRunLoopDefaultMode);
166 CFRelease(mySession->serverRunLoopSource);
167 }
168 CFMachPortInvalidate(mySession->serverPort);
169 CFRelease(mySession->serverPort);
170
171 CFRelease(sessionPrivate->keys);
172 CFRelease(sessionPrivate->reKeys);
173 CFAllocatorDeallocate(NULL, sessionPrivate);
174 *session = NULL;
175
176 return SCD_OK;
177 }
178
179
180 kern_return_t
181 _configclose(mach_port_t server, int *scd_status)
182 {
183 serverSessionRef mySession = getSession(server);
184
185 SCDLog(LOG_DEBUG, CFSTR("Close session."));
186 SCDLog(LOG_DEBUG, CFSTR(" server = %d"), server);
187
188 /*
189 * Close the session.
190 */
191 *scd_status = _SCDClose(&mySession->session);
192 if (*scd_status != SCD_OK) {
193 SCDLog(LOG_DEBUG, CFSTR(" _SCDClose(): %s"), SCDError(*scd_status));
194 return KERN_SUCCESS;
195 }
196
197 /*
198 * Remove the session entry.
199 */
200 removeSession(server);
201
202 return KERN_SUCCESS;
203 }