]> git.saurik.com Git - apple/configd.git/blob - configd.tproj/_configremove.c
configd-24.tar.gz
[apple/configd.git] / configd.tproj / _configremove.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 _SCDRemove(SCDSessionRef session, CFStringRef key)
28 {
29 SCDSessionPrivateRef sessionPrivate = (SCDSessionPrivateRef)session;
30 SCDStatus scd_status = SCD_OK;
31 boolean_t wasLocked;
32 CFDictionaryRef dict;
33 CFMutableDictionaryRef newDict;
34 CFStringRef sessionKey;
35
36 SCDLog(LOG_DEBUG, CFSTR("_SCDRemove:"));
37 SCDLog(LOG_DEBUG, CFSTR(" key = %@"), key);
38
39 if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
40 return SCD_NOSESSION; /* you can't do anything with a closed session */
41 }
42
43 /*
44 * 1. Determine if the cache lock is currently held and acquire
45 * the lock if necessary.
46 */
47 wasLocked = SCDOptionGet(NULL, kSCDOptionIsLocked);
48 if (!wasLocked) {
49 scd_status = _SCDLock(session);
50 if (scd_status != SCD_OK) {
51 SCDLog(LOG_DEBUG, CFSTR(" _SCDLock(): %s"), SCDError(scd_status));
52 return scd_status;
53 }
54 }
55
56 /*
57 * 2. Ensure that this key exists.
58 */
59 dict = CFDictionaryGetValue(cacheData, key);
60 if ((dict == NULL) || (CFDictionaryContainsKey(dict, kSCDData) == FALSE)) {
61 /* key doesn't exist (or data never defined) */
62 scd_status = SCD_NOKEY;
63 goto done;
64 }
65 newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
66
67 /*
68 * 3. Mark this key as "changed". Any "watchers" will be
69 * notified as soon as the lock is released.
70 */
71 CFSetAddValue(changedKeys, key);
72
73 /*
74 * 4. Add this key to a deferred cleanup list so that, after
75 * the change notifications are posted, any associated
76 * regex keys can be removed.
77 */
78 CFSetAddValue(deferredRemovals, key);
79
80 /*
81 * 5. Check if this is a session key and, if so, add it
82 * to the (session) removal list
83 */
84 sessionKey = CFDictionaryGetValue(newDict, kSCDSession);
85 if (sessionKey) {
86 CFStringRef removedKey;
87
88 /* We are no longer a session key! */
89 CFDictionaryRemoveValue(newDict, kSCDSession);
90
91 /* add this session key to the (session) removal list */
92 removedKey = CFStringCreateWithFormat(NULL, 0, CFSTR("%@:%@"), sessionKey, key);
93 CFSetAddValue(removedSessionKeys, removedKey);
94 CFRelease(removedKey);
95 }
96
97 /*
98 * 6. Remove data, remove instance, and update/remove
99 * the dictionary cache entry.
100 */
101 CFDictionaryRemoveValue(newDict, kSCDData);
102 CFDictionaryRemoveValue(newDict, kSCDInstance);
103 if (CFDictionaryGetCount(newDict) > 0) {
104 /* this key is still being "watched" */
105 CFDictionarySetValue(cacheData, key, newDict);
106 } else {
107 /* no information left, remove the empty dictionary */
108 CFDictionaryRemoveValue(cacheData, key);
109 }
110 CFRelease(newDict);
111
112 /*
113 * 7. Release the lock if we acquired it as part of this request.
114 */
115 done:
116 if (!wasLocked)
117 _SCDUnlock(session);
118
119 return scd_status;
120 }
121
122
123 kern_return_t
124 _configremove(mach_port_t server,
125 xmlData_t keyRef, /* raw XML bytes */
126 mach_msg_type_number_t keyLen,
127 int *scd_status
128 )
129 {
130 kern_return_t status;
131 serverSessionRef mySession = getSession(server);
132 CFDataRef xmlKey; /* key (XML serialized) */
133 CFStringRef key; /* key (un-serialized) */
134 CFStringRef xmlError;
135
136 SCDLog(LOG_DEBUG, CFSTR("Remove key from configuration database."));
137 SCDLog(LOG_DEBUG, CFSTR(" server = %d"), server);
138
139 /* un-serialize the key */
140 xmlKey = CFDataCreate(NULL, keyRef, keyLen);
141 status = vm_deallocate(mach_task_self(), (vm_address_t)keyRef, keyLen);
142 if (status != KERN_SUCCESS) {
143 SCDLog(LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
144 /* non-fatal???, proceed */
145 }
146 key = CFPropertyListCreateFromXMLData(NULL,
147 xmlKey,
148 kCFPropertyListImmutable,
149 &xmlError);
150 CFRelease(xmlKey);
151 if (xmlError) {
152 SCDLog(LOG_DEBUG, CFSTR("CFPropertyListCreateFromXMLData() key: %s"), xmlError);
153 *scd_status = SCD_FAILED;
154 return KERN_SUCCESS;
155 }
156
157 *scd_status = _SCDRemove(mySession->session, key);
158 CFRelease(key);
159
160 return KERN_SUCCESS;
161 }
162