]> git.saurik.com Git - apple/configd.git/blob - configd.tproj/_configadd_s.c
configd-42.tar.gz
[apple/configd.git] / configd.tproj / _configadd_s.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 * October 17, 2000 Allan Nathanson <ajn@apple.com>
30 * - initial revision
31 */
32
33 #include "configd.h"
34 #include "session.h"
35
36 int
37 __SCDynamicStoreAddTemporaryValue(SCDynamicStoreRef store, CFStringRef key, CFPropertyListRef value)
38 {
39 SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
40 int sc_status = kSCStatusOK;
41 CFStringRef sessionKey;
42 CFDictionaryRef dict;
43 CFMutableDictionaryRef newDict;
44 CFArrayRef keys;
45 CFMutableArrayRef newKeys;
46
47 SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreAddTemporaryValue:"));
48 SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" key = %@"), key);
49 SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" value = %@"), value);
50
51 if (!store || (storePrivate->server == MACH_PORT_NULL)) {
52 return kSCStatusNoStoreSession; /* you must have an open session to play */
53 }
54
55 /*
56 * 1. Add the key
57 */
58 sc_status = __SCDynamicStoreAddValue(store, key, value);
59 if (sc_status != kSCStatusOK) {
60 SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" __SCDynamicStoreAddValue(): %s"), SCErrorString(sc_status));
61 return sc_status;
62 }
63
64 /*
65 * 2. Create the session key
66 */
67 sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), storePrivate->server);
68
69 /*
70 * 3. Add this key to my list of per-session keys
71 */
72 dict = CFDictionaryGetValue(sessionData, sessionKey);
73 keys = CFDictionaryGetValue(dict, kSCDSessionKeys);
74 if ((keys == NULL) ||
75 (CFArrayGetFirstIndexOfValue(keys,
76 CFRangeMake(0, CFArrayGetCount(keys)),
77 key) == -1)) {
78 /*
79 * if no session keys defined "or" keys defined but not
80 * this one...
81 */
82 if (keys) {
83 /* this is a new session key */
84 newKeys = CFArrayCreateMutableCopy(NULL, 0, keys);
85 } else {
86 /* this is an additional session key */
87 newKeys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
88 }
89 CFArrayAppendValue(newKeys, key);
90
91 /* update session dictionary */
92 newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
93 CFDictionarySetValue(newDict, kSCDSessionKeys, newKeys);
94 CFRelease(newKeys);
95 CFDictionarySetValue(sessionData, sessionKey, newDict);
96 CFRelease(newDict);
97 }
98
99 /*
100 * 4. Mark the key as a "session" key and track the creator.
101 */
102 dict = CFDictionaryGetValue(storeData, key);
103 newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
104 CFDictionarySetValue(newDict, kSCDSession, sessionKey);
105 CFDictionarySetValue(storeData, key, newDict);
106 CFRelease(newDict);
107
108 CFRelease(sessionKey);
109 return sc_status;
110 }
111
112
113 kern_return_t
114 _configadd_s(mach_port_t server,
115 xmlData_t keyRef, /* raw XML bytes */
116 mach_msg_type_number_t keyLen,
117 xmlData_t dataRef, /* raw XML bytes */
118 mach_msg_type_number_t dataLen,
119 int *newInstance,
120 int *sc_status
121 )
122 {
123 kern_return_t status;
124 serverSessionRef mySession = getSession(server);
125 CFDataRef xmlKey; /* key (XML serialized) */
126 CFStringRef key; /* key (un-serialized) */
127 CFDataRef xmlData; /* data (XML serialized) */
128 CFPropertyListRef data; /* data (un-serialized) */
129 CFStringRef xmlError;
130
131 SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Add (session) key to configuration database."));
132 SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
133
134 *sc_status = kSCStatusOK;
135
136 /* un-serialize the key */
137 xmlKey = CFDataCreate(NULL, keyRef, keyLen);
138 status = vm_deallocate(mach_task_self(), (vm_address_t)keyRef, keyLen);
139 if (status != KERN_SUCCESS) {
140 SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
141 /* non-fatal???, proceed */
142 }
143 key = CFPropertyListCreateFromXMLData(NULL,
144 xmlKey,
145 kCFPropertyListImmutable,
146 &xmlError);
147 CFRelease(xmlKey);
148 if (!key) {
149 if (xmlError) {
150 SCLog(_configd_verbose, LOG_DEBUG,
151 CFSTR("CFPropertyListCreateFromXMLData() key: %@"),
152 xmlError);
153 CFRelease(xmlError);
154 }
155 *sc_status = kSCStatusFailed;
156 } else if (!isA_CFString(key)) {
157 *sc_status = kSCStatusInvalidArgument;
158 }
159
160 /* un-serialize the data */
161 xmlData = CFDataCreate(NULL, dataRef, dataLen);
162 status = vm_deallocate(mach_task_self(), (vm_address_t)dataRef, dataLen);
163 if (status != KERN_SUCCESS) {
164 SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
165 /* non-fatal???, proceed */
166 }
167 data = CFPropertyListCreateFromXMLData(NULL,
168 xmlData,
169 kCFPropertyListImmutable,
170 &xmlError);
171 CFRelease(xmlData);
172 if (!data) {
173 if (xmlError) {
174 SCLog(_configd_verbose, LOG_DEBUG,
175 CFSTR("CFPropertyListCreateFromXMLData() data: %@"),
176 xmlError);
177 CFRelease(xmlError);
178 }
179 *sc_status = kSCStatusFailed;
180 } else if (!isA_CFPropertyList(data)) {
181 *sc_status = kSCStatusInvalidArgument;
182 }
183
184 if (*sc_status != kSCStatusOK) {
185 if (key) CFRelease(key);
186 if (data) CFRelease(data);
187 return KERN_SUCCESS;
188 }
189
190 *sc_status = __SCDynamicStoreAddTemporaryValue(mySession->store, key, data);
191 if (*sc_status == kSCStatusOK) {
192 *newInstance = 1;
193 }
194 CFRelease(key);
195 CFRelease(data);
196
197 return KERN_SUCCESS;
198 }