]> git.saurik.com Git - apple/configd.git/blob - configd.tproj/_configclose.c
configd-42.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 /*
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 if ((keyCnt = CFSetGetCount(storePrivate->keys)) > 0) {
83 void **watchedKeys;
84 CFArrayRef keysToRemove;
85 CFIndex i;
86
87 watchedKeys = CFAllocatorAllocate(NULL, keyCnt * sizeof(CFStringRef), 0);
88 CFSetGetValues(storePrivate->keys, watchedKeys);
89 keysToRemove = CFArrayCreate(NULL, watchedKeys, keyCnt, &kCFTypeArrayCallBacks);
90 CFAllocatorDeallocate(NULL, watchedKeys);
91 for (i=0; i<keyCnt; i++) {
92 (void) __SCDynamicStoreRemoveWatchedKey(*store,
93 CFArrayGetValueAtIndex(keysToRemove, i),
94 FALSE);
95 }
96 CFRelease(keysToRemove);
97 }
98
99 /* Remove regex notification keys */
100 if ((keyCnt = CFSetGetCount(storePrivate->reKeys)) > 0) {
101 void **watchedKeys;
102 CFArrayRef keysToRemove;
103 CFIndex i;
104
105 watchedKeys = CFAllocatorAllocate(NULL, keyCnt * sizeof(CFStringRef), 0);
106 CFSetGetValues(storePrivate->reKeys, watchedKeys);
107 keysToRemove = CFArrayCreate(NULL, watchedKeys, keyCnt, &kCFTypeArrayCallBacks);
108 CFAllocatorDeallocate(NULL, watchedKeys);
109 for (i=0; i<keyCnt; i++) {
110 (void) __SCDynamicStoreRemoveWatchedKey(*store,
111 CFArrayGetValueAtIndex(keysToRemove, i),
112 TRUE);
113 }
114 CFRelease(keysToRemove);
115 }
116
117 /* Remove/cancel any outstanding notification requests. */
118 (void) __SCDynamicStoreNotifyCancel(*store);
119
120 /* Remove any session keys */
121 sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), storePrivate->server);
122 dict = CFDictionaryGetValue(sessionData, sessionKey);
123 keys = CFDictionaryGetValue(dict, kSCDSessionKeys);
124 if (keys && ((keyCnt = CFArrayGetCount(keys)) > 0)) {
125 Boolean wasLocked;
126 CFIndex i;
127
128 /*
129 * if necessary, claim a lock to ensure that we inform
130 * any processes that a session key was removed.
131 */
132 wasLocked = (storeLocked > 0);
133 if (!wasLocked) {
134 (void) __SCDynamicStoreLock(*store, FALSE);
135 }
136
137 /* remove keys from "locked" store" */
138 for (i=0; i<keyCnt; i++) {
139 if (isMySessionKey(sessionKey, CFArrayGetValueAtIndex(keys, i))) {
140 (void) __SCDynamicStoreRemoveValue(*store, CFArrayGetValueAtIndex(keys, i));
141 }
142 }
143
144 if (wasLocked) {
145 /* remove keys from "unlocked" store" */
146 _swapLockedStoreData();
147 for (i=0; i<keyCnt; i++) {
148 if (isMySessionKey(sessionKey, CFArrayGetValueAtIndex(keys, i)))
149 (void) __SCDynamicStoreRemoveValue(*store, CFArrayGetValueAtIndex(keys, i));
150 }
151 _swapLockedStoreData();
152 }
153
154 /*
155 * Note: everyone who calls __SCDynamicStoreClose() ends
156 * up removing this sessions dictionary. As such,
157 * we don't need to worry about the session keys.
158 */
159 }
160 CFRelease(sessionKey);
161
162 /* release the lock */
163 if (storePrivate->locked) {
164 (void) __SCDynamicStoreUnlock(*store, FALSE);
165 }
166
167 /*
168 * Remove the run loop source on the server port (for this
169 * client). Then, invalidate and release the port.
170 */
171 mySession = getSession(storePrivate->server);
172 if (mySession->serverRunLoopSource) {
173 CFRunLoopRemoveSource(CFRunLoopGetCurrent(),
174 mySession->serverRunLoopSource,
175 kCFRunLoopDefaultMode);
176 CFRelease(mySession->serverRunLoopSource);
177 }
178 CFMachPortInvalidate(mySession->serverPort);
179 CFRelease(mySession->serverPort);
180
181 storePrivate->server = MACH_PORT_NULL;
182 CFRelease(*store);
183 *store = NULL;
184
185 return kSCStatusOK;
186 }
187
188
189 kern_return_t
190 _configclose(mach_port_t server, int *sc_status)
191 {
192 serverSessionRef mySession = getSession(server);
193
194 SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Close session."));
195 SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
196
197 /*
198 * Close the session.
199 */
200 *sc_status = __SCDynamicStoreClose(&mySession->store);
201 if (*sc_status != kSCStatusOK) {
202 SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" __SCDynamicStoreClose(): %s"), SCErrorString(*sc_status));
203 return KERN_SUCCESS;
204 }
205
206 /*
207 * Remove the session entry.
208 */
209 removeSession(server);
210
211 return KERN_SUCCESS;
212 }