]> git.saurik.com Git - apple/configd.git/blob - configd.tproj/_configclose.c
configd-53.tar.gz
[apple/configd.git] / configd.tproj / _configclose.c
1 /*
2 * Copyright (c) 2000-2002 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 /*
24 * Modification History
25 *
26 * June 1, 2001 Allan Nathanson <ajn@apple.com>
27 * - public API conversion
28 *
29 * March 24, 2000 Allan Nathanson <ajn@apple.com>
30 * - initial revision
31 */
32
33 #include <unistd.h>
34
35 #include "configd.h"
36 #include "session.h"
37
38 static Boolean
39 isMySessionKey(CFStringRef sessionKey, CFStringRef key)
40 {
41 CFDictionaryRef dict;
42 CFStringRef storeSessionKey;
43
44 dict = CFDictionaryGetValue(storeData, key);
45 if (!dict) {
46 /* if key no longer exists */
47 return FALSE;
48 }
49
50 storeSessionKey = CFDictionaryGetValue(dict, kSCDSession);
51 if (!storeSessionKey) {
52 /* if this is not a session key */
53 return FALSE;
54 }
55
56 if (!CFEqual(sessionKey, storeSessionKey)) {
57 /* if this is not "my" session key */
58 return FALSE;
59 }
60
61 return TRUE;
62 }
63
64
65 int
66 __SCDynamicStoreClose(SCDynamicStoreRef *store)
67 {
68 SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)*store;
69 CFIndex keyCnt;
70 CFStringRef sessionKey;
71 CFDictionaryRef dict;
72 CFArrayRef keys;
73 serverSessionRef mySession;
74
75 SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreClose:"));
76
77 if ((*store == NULL) || (storePrivate->server == MACH_PORT_NULL)) {
78 return kSCStatusNoStoreSession; /* you must have an open session to play */
79 }
80
81 /* Remove notification keys */
82 keyCnt = CFSetGetCount(storePrivate->keys);
83 if (keyCnt > 0) {
84 const void **watchedKeys;
85 CFArrayRef keysToRemove;
86 CFIndex i;
87
88 watchedKeys = CFAllocatorAllocate(NULL, keyCnt * sizeof(CFStringRef), 0);
89 CFSetGetValues(storePrivate->keys, watchedKeys);
90 keysToRemove = CFArrayCreate(NULL, watchedKeys, keyCnt, &kCFTypeArrayCallBacks);
91 CFAllocatorDeallocate(NULL, watchedKeys);
92 for (i=0; i<keyCnt; i++) {
93 (void) __SCDynamicStoreRemoveWatchedKey(*store,
94 CFArrayGetValueAtIndex(keysToRemove, i),
95 FALSE);
96 }
97 CFRelease(keysToRemove);
98 }
99
100 /* Remove regex notification keys */
101 keyCnt = CFSetGetCount(storePrivate->reKeys);
102 if (keyCnt > 0) {
103 const void **watchedKeys;
104 CFArrayRef keysToRemove;
105 CFIndex i;
106
107 watchedKeys = CFAllocatorAllocate(NULL, keyCnt * sizeof(CFStringRef), 0);
108 CFSetGetValues(storePrivate->reKeys, watchedKeys);
109 keysToRemove = CFArrayCreate(NULL, watchedKeys, keyCnt, &kCFTypeArrayCallBacks);
110 CFAllocatorDeallocate(NULL, watchedKeys);
111 for (i=0; i<keyCnt; i++) {
112 (void) __SCDynamicStoreRemoveWatchedKey(*store,
113 CFArrayGetValueAtIndex(keysToRemove, i),
114 TRUE);
115 }
116 CFRelease(keysToRemove);
117 }
118
119 /* Remove/cancel any outstanding notification requests. */
120 (void) __SCDynamicStoreNotifyCancel(*store);
121
122 /* Remove any session keys */
123 sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), storePrivate->server);
124 dict = CFDictionaryGetValue(sessionData, sessionKey);
125 keys = CFDictionaryGetValue(dict, kSCDSessionKeys);
126 if (keys && ((keyCnt = CFArrayGetCount(keys)) > 0)) {
127 Boolean wasLocked;
128 CFIndex i;
129
130 /*
131 * if necessary, claim a lock to ensure that we inform
132 * any processes that a session key was removed.
133 */
134 wasLocked = (storeLocked > 0);
135 if (!wasLocked) {
136 (void) __SCDynamicStoreLock(*store, FALSE);
137 }
138
139 /* remove keys from "locked" store" */
140 for (i=0; i<keyCnt; i++) {
141 if (isMySessionKey(sessionKey, CFArrayGetValueAtIndex(keys, i))) {
142 (void) __SCDynamicStoreRemoveValue(*store, CFArrayGetValueAtIndex(keys, i));
143 }
144 }
145
146 if (wasLocked) {
147 /* remove keys from "unlocked" store" */
148 _swapLockedStoreData();
149 for (i=0; i<keyCnt; i++) {
150 if (isMySessionKey(sessionKey, CFArrayGetValueAtIndex(keys, i)))
151 (void) __SCDynamicStoreRemoveValue(*store, CFArrayGetValueAtIndex(keys, i));
152 }
153 _swapLockedStoreData();
154 }
155
156 /*
157 * Note: everyone who calls __SCDynamicStoreClose() ends
158 * up removing this sessions dictionary. As such,
159 * we don't need to worry about the session keys.
160 */
161 }
162 CFRelease(sessionKey);
163
164 /* release the lock */
165 if (storePrivate->locked) {
166 (void) __SCDynamicStoreUnlock(*store, FALSE);
167 }
168
169 /*
170 * Remove the run loop source on the server port (for this
171 * client). Then, invalidate and release the port.
172 */
173 mySession = getSession(storePrivate->server);
174 if (mySession->serverRunLoopSource) {
175 CFRunLoopRemoveSource(CFRunLoopGetCurrent(),
176 mySession->serverRunLoopSource,
177 kCFRunLoopDefaultMode);
178 CFRelease(mySession->serverRunLoopSource);
179 }
180 CFMachPortInvalidate(mySession->serverPort);
181 CFRelease(mySession->serverPort);
182
183 storePrivate->server = MACH_PORT_NULL;
184 CFRelease(*store);
185 *store = NULL;
186
187 return kSCStatusOK;
188 }
189
190
191 kern_return_t
192 _configclose(mach_port_t server, int *sc_status)
193 {
194 serverSessionRef mySession = getSession(server);
195
196 SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Close session."));
197 SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
198
199 /*
200 * Close the session.
201 */
202 *sc_status = __SCDynamicStoreClose(&mySession->store);
203 if (*sc_status != kSCStatusOK) {
204 SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" __SCDynamicStoreClose(): %s"), SCErrorString(*sc_status));
205 return KERN_SUCCESS;
206 }
207
208 /*
209 * Remove the session entry.
210 */
211 removeSession(server);
212
213 return KERN_SUCCESS;
214 }