]> git.saurik.com Git - apple/configd.git/blob - configd.tproj/_configopen.c
configd-53.tar.gz
[apple/configd.git] / configd.tproj / _configopen.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 "configd.h"
34 #include "configd_server.h"
35 #include "session.h"
36
37 int
38 __SCDynamicStoreOpen(SCDynamicStoreRef *store, CFStringRef name)
39 {
40 SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreOpen:"));
41 SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" name = %@"), name);
42
43 /*
44 * allocate and initialize a new session
45 */
46 *store = __SCDynamicStoreCreatePrivate(NULL, name, NULL, NULL);
47
48 /*
49 * If necessary, initialize the store and session data dictionaries
50 */
51 if (storeData == NULL) {
52 storeData = CFDictionaryCreateMutable(NULL,
53 0,
54 &kCFTypeDictionaryKeyCallBacks,
55 &kCFTypeDictionaryValueCallBacks);
56 sessionData = CFDictionaryCreateMutable(NULL,
57 0,
58 &kCFTypeDictionaryKeyCallBacks,
59 &kCFTypeDictionaryValueCallBacks);
60 changedKeys = CFSetCreateMutable(NULL,
61 0,
62 &kCFTypeSetCallBacks);
63 deferredRemovals = CFSetCreateMutable(NULL,
64 0,
65 &kCFTypeSetCallBacks);
66 removedSessionKeys = CFSetCreateMutable(NULL,
67 0,
68 &kCFTypeSetCallBacks);
69 }
70
71 return kSCStatusOK;
72 }
73
74
75 kern_return_t
76 _configopen(mach_port_t server,
77 xmlData_t nameRef, /* raw XML bytes */
78 mach_msg_type_number_t nameLen,
79 mach_port_t *newServer,
80 int *sc_status)
81 {
82 kern_return_t status;
83 serverSessionRef mySession, newSession;
84 CFStringRef name; /* name (un-serialized) */
85 mach_port_t oldNotify;
86 CFStringRef sessionKey;
87 CFDictionaryRef info;
88 CFMutableDictionaryRef newInfo;
89 CFMachPortRef mp;
90
91 SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Open new session."));
92 SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
93
94 /* un-serialize the name */
95 if (!_SCUnserialize((CFPropertyListRef *)&name, (void *)nameRef, nameLen)) {
96 *sc_status = kSCStatusFailed;
97 return KERN_SUCCESS;
98 }
99
100 if (!isA_CFString(name)) {
101 CFRelease(name);
102 *sc_status = kSCStatusInvalidArgument;
103 return KERN_SUCCESS;
104 }
105
106 mySession = getSession(server);
107 if (mySession->store) {
108 CFRelease(name);
109 SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" Sorry, this session is already open."));
110 *sc_status = kSCStatusFailed; /* you can't re-open an "open" session */
111 return KERN_SUCCESS;
112 }
113
114 /* Create the server port for this session */
115 mp = CFMachPortCreate(NULL, configdCallback, NULL, NULL);
116
117 /* return the newly allocated port to be used for this session */
118 *newServer = CFMachPortGetPort(mp);
119
120 /*
121 * establish the new session
122 */
123 newSession = addSession(mp);
124
125 /* Create and add a run loop source for the port */
126 newSession->serverRunLoopSource = CFMachPortCreateRunLoopSource(NULL, mp, 0);
127 CFRunLoopAddSource(CFRunLoopGetCurrent(),
128 newSession->serverRunLoopSource,
129 kCFRunLoopDefaultMode);
130
131 /*
132 * save the credentials associated with the caller.
133 */
134 newSession->callerEUID = mySession->callerEUID;
135 newSession->callerEGID = mySession->callerEGID;
136
137 *sc_status = __SCDynamicStoreOpen(&newSession->store, name);
138
139 /*
140 * Make the server port accessible to the framework routines.
141 */
142 ((SCDynamicStorePrivateRef)newSession->store)->server = *newServer;
143
144 /* Request a notification when/if the client dies */
145 status = mach_port_request_notification(mach_task_self(),
146 *newServer,
147 MACH_NOTIFY_NO_SENDERS,
148 1,
149 *newServer,
150 MACH_MSG_TYPE_MAKE_SEND_ONCE,
151 &oldNotify);
152 if (status != KERN_SUCCESS) {
153 SCLog(_configd_verbose, LOG_DEBUG, CFSTR("mach_port_request_notification(): %s"), mach_error_string(status));
154 CFRelease(name);
155 cleanupSession(*newServer);
156 *newServer = MACH_PORT_NULL;
157 *sc_status = kSCStatusFailed;
158 return KERN_SUCCESS;
159 }
160
161 if (oldNotify != MACH_PORT_NULL) {
162 SCLog(_configd_verbose, LOG_ERR, CFSTR("_configopen(): why is oldNotify != MACH_PORT_NULL?"));
163 }
164
165 /*
166 * Save the name of the calling application / plug-in with the session data.
167 */
168 sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), *newServer);
169 info = CFDictionaryGetValue(sessionData, sessionKey);
170 if (info) {
171 newInfo = CFDictionaryCreateMutableCopy(NULL, 0, info);
172 } else {
173 newInfo = CFDictionaryCreateMutable(NULL,
174 0,
175 &kCFTypeDictionaryKeyCallBacks,
176 &kCFTypeDictionaryValueCallBacks);
177 }
178 CFDictionarySetValue(newInfo, kSCDName, name);
179 CFRelease(name);
180 CFDictionarySetValue(sessionData, sessionKey, newInfo);
181 CFRelease(newInfo);
182 CFRelease(sessionKey);
183
184 return KERN_SUCCESS;
185 }