]> git.saurik.com Git - apple/configd.git/blob - configd.tproj/_configopen.c
82630c9f77247217070c01e15bf02a63d84fc9cb
[apple/configd.git] / configd.tproj / _configopen.c
1 /*
2 * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /*
25 * Modification History
26 *
27 * June 1, 2001 Allan Nathanson <ajn@apple.com>
28 * - public API conversion
29 *
30 * March 24, 2000 Allan Nathanson <ajn@apple.com>
31 * - initial revision
32 */
33
34 #include "configd.h"
35 #include "configd_server.h"
36 #include "session.h"
37
38 __private_extern__
39 int
40 __SCDynamicStoreOpen(SCDynamicStoreRef *store, CFStringRef name)
41 {
42 if (_configd_verbose) {
43 SCLog(TRUE, LOG_DEBUG, CFSTR("__SCDynamicStoreOpen:"));
44 SCLog(TRUE, LOG_DEBUG, CFSTR(" name = %@"), name);
45 }
46
47 /*
48 * allocate and initialize a new session
49 */
50 *store = (SCDynamicStoreRef)__SCDynamicStoreCreatePrivate(NULL, name, NULL, NULL);
51
52 /*
53 * If necessary, initialize the store and session data dictionaries
54 */
55 if (storeData == NULL) {
56 sessionData = CFDictionaryCreateMutable(NULL,
57 0,
58 &kCFTypeDictionaryKeyCallBacks,
59 &kCFTypeDictionaryValueCallBacks);
60 storeData = CFDictionaryCreateMutable(NULL,
61 0,
62 &kCFTypeDictionaryKeyCallBacks,
63 &kCFTypeDictionaryValueCallBacks);
64 patternData = CFDictionaryCreateMutable(NULL,
65 0,
66 &kCFTypeDictionaryKeyCallBacks,
67 &kCFTypeDictionaryValueCallBacks);
68 changedKeys = CFSetCreateMutable(NULL,
69 0,
70 &kCFTypeSetCallBacks);
71 deferredRemovals = CFSetCreateMutable(NULL,
72 0,
73 &kCFTypeSetCallBacks);
74 removedSessionKeys = CFSetCreateMutable(NULL,
75 0,
76 &kCFTypeSetCallBacks);
77 }
78
79 return kSCStatusOK;
80 }
81
82
83 __private_extern__
84 kern_return_t
85 _configopen(mach_port_t server,
86 xmlData_t nameRef, /* raw XML bytes */
87 mach_msg_type_number_t nameLen,
88 mach_port_t *newServer,
89 int *sc_status)
90 {
91 kern_return_t status;
92 serverSessionRef mySession, newSession;
93 CFStringRef name; /* name (un-serialized) */
94 mach_port_t oldNotify;
95 CFStringRef sessionKey;
96 CFDictionaryRef info;
97 CFMutableDictionaryRef newInfo;
98 CFMachPortRef mp;
99
100 if (_configd_verbose) {
101 SCLog(TRUE, LOG_DEBUG, CFSTR("Open new session."));
102 SCLog(TRUE, LOG_DEBUG, CFSTR(" server = %d"), server);
103 }
104
105 /* un-serialize the name */
106 if (!_SCUnserializeString(&name, NULL, (void *)nameRef, nameLen)) {
107 *sc_status = kSCStatusFailed;
108 return KERN_SUCCESS;
109 }
110
111 if (!isA_CFString(name)) {
112 CFRelease(name);
113 *sc_status = kSCStatusInvalidArgument;
114 return KERN_SUCCESS;
115 }
116
117 mySession = getSession(server);
118 if (mySession->store) {
119 CFRelease(name);
120 SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" Sorry, this session is already open."));
121 *sc_status = kSCStatusFailed; /* you can't re-open an "open" session */
122 return KERN_SUCCESS;
123 }
124
125 /* Create the server port for this session */
126 mp = CFMachPortCreate(NULL, configdCallback, NULL, NULL);
127
128 /* return the newly allocated port to be used for this session */
129 *newServer = CFMachPortGetPort(mp);
130
131 /*
132 * establish the new session
133 */
134 newSession = addSession(mp);
135
136 /* Create and add a run loop source for the port */
137 newSession->serverRunLoopSource = CFMachPortCreateRunLoopSource(NULL, mp, 0);
138 CFRunLoopAddSource(CFRunLoopGetCurrent(),
139 newSession->serverRunLoopSource,
140 kCFRunLoopDefaultMode);
141
142 /*
143 * save the credentials associated with the caller.
144 */
145 newSession->callerEUID = mySession->callerEUID;
146 newSession->callerEGID = mySession->callerEGID;
147
148 if (_configd_trace) {
149 SCTrace(TRUE, _configd_trace, CFSTR("open : %5d : %@\n"), *newServer, name);
150 }
151
152 *sc_status = __SCDynamicStoreOpen(&newSession->store, name);
153
154 /*
155 * Make the server port accessible to the framework routines.
156 */
157 ((SCDynamicStorePrivateRef)newSession->store)->server = *newServer;
158
159 /* Request a notification when/if the client dies */
160 status = mach_port_request_notification(mach_task_self(),
161 *newServer,
162 MACH_NOTIFY_NO_SENDERS,
163 1,
164 *newServer,
165 MACH_MSG_TYPE_MAKE_SEND_ONCE,
166 &oldNotify);
167 if (status != KERN_SUCCESS) {
168 SCLog(_configd_verbose, LOG_DEBUG, CFSTR("mach_port_request_notification(): %s"), mach_error_string(status));
169 CFRelease(name);
170 cleanupSession(*newServer);
171 *newServer = MACH_PORT_NULL;
172 *sc_status = kSCStatusFailed;
173 return KERN_SUCCESS;
174 }
175
176 if (oldNotify != MACH_PORT_NULL) {
177 SCLog(_configd_verbose, LOG_ERR, CFSTR("_configopen(): why is oldNotify != MACH_PORT_NULL?"));
178 }
179
180 /*
181 * Save the name of the calling application / plug-in with the session data.
182 */
183 sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), *newServer);
184 info = CFDictionaryGetValue(sessionData, sessionKey);
185 if (info) {
186 newInfo = CFDictionaryCreateMutableCopy(NULL, 0, info);
187 } else {
188 newInfo = CFDictionaryCreateMutable(NULL,
189 0,
190 &kCFTypeDictionaryKeyCallBacks,
191 &kCFTypeDictionaryValueCallBacks);
192 }
193 CFDictionarySetValue(newInfo, kSCDName, name);
194 CFRelease(name);
195 CFDictionarySetValue(sessionData, sessionKey, newInfo);
196 CFRelease(newInfo);
197 CFRelease(sessionKey);
198
199 return KERN_SUCCESS;
200 }