2 * Copyright (c) 2000, 2001, 2003-2005, 2007 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 * Modification History
27 * June 1, 2001 Allan Nathanson <ajn@apple.com>
28 * - public API conversion
30 * March 24, 2000 Allan Nathanson <ajn@apple.com>
35 #include "configd_server.h"
38 /* information maintained for each active session */
39 static serverSessionRef
*sessions
= NULL
;
40 static int nSessions
= 0;
45 getSession(mach_port_t server
)
49 if (server
== MACH_PORT_NULL
) {
50 SCLog(TRUE
, LOG_NOTICE
, CFSTR("Excuse me, why is getSession() being called with an invalid port?"));
54 for (i
= 0; i
< nSessions
; i
++) {
55 serverSessionRef thisSession
= sessions
[i
];
57 if (thisSession
== NULL
) {
58 /* found an empty slot, skip it */
60 } else if (thisSession
->key
== server
) {
61 return thisSession
; /* we've seen this server before */
62 } else if (thisSession
->store
&&
63 (((SCDynamicStorePrivateRef
)thisSession
->store
)->notifySignalTask
== server
)) {
68 /* no sessions available */
75 addSession(mach_port_t server
, CFStringRef (*copyDescription
)(const void *info
))
77 CFMachPortContext context
= { 0, NULL
, NULL
, NULL
, NULL
};
81 /* new session (actually, the first) found */
82 sessions
= malloc(sizeof(serverSessionRef
));
88 for (i
= 0; i
< nSessions
; i
++) {
89 if (sessions
[i
] == NULL
) {
90 /* found an empty slot, use it */
95 /* new session identified */
97 /* no empty slots, add one to the list */
99 sessions
= reallocf(sessions
, ((nSessions
) * sizeof(serverSessionRef
)));
103 // allocate a new session for this server
104 sessions
[n
] = malloc(sizeof(serverSession
));
105 bzero(sessions
[n
], sizeof(serverSession
));
107 // create server port
108 context
.info
= sessions
[n
];
109 context
.copyDescription
= copyDescription
;
111 if (server
== MACH_PORT_NULL
) {
112 // SCDynamicStore client ports
113 (void) mach_port_allocate(mach_task_self(),
114 MACH_PORT_RIGHT_RECEIVE
,
116 (void) mach_port_insert_right(mach_task_self(),
119 MACH_MSG_TYPE_MAKE_SEND
);
121 sessions
[n
]->key
= server
;
122 sessions
[n
]->serverPort
= CFMachPortCreateWithPort(NULL
,
127 // sessions[n]->serverRunLoopSource = NULL;
128 // sessions[n]->store = NULL;
129 sessions
[n
]->callerEUID
= 1; /* not "root" */
137 removeSession(mach_port_t server
)
140 serverSessionRef thisSession
;
141 CFStringRef sessionKey
;
143 for (i
= 0; i
< nSessions
; i
++) {
144 thisSession
= sessions
[i
];
146 if (thisSession
== NULL
) {
147 /* found an empty slot, skip it */
149 } else if (thisSession
->key
== server
) {
151 * We don't need any remaining information in the
152 * sessionData dictionary, remove it.
154 sessionKey
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%d"), server
);
155 CFDictionaryRemoveValue(sessionData
, sessionKey
);
156 CFRelease(sessionKey
);
159 * Lastly, get rid of the per-session structure.
174 cleanupSession(mach_port_t server
)
178 for (i
= 0; i
< nSessions
; i
++) {
179 serverSessionRef thisSession
= sessions
[i
];
181 if ((thisSession
!= NULL
) && (thisSession
->key
== server
)) {
183 * session entry still exists.
186 if (_configd_trace
) {
187 SCTrace(TRUE
, _configd_trace
, CFSTR("cleanup : %5d\n"), server
);
191 * Ensure that any changes made while we held the "lock"
194 if ((storeLocked
> 0) &&
195 ((SCDynamicStorePrivateRef
)thisSession
->store
)->locked
) {
197 * swap store and associated data which, after
198 * being closed, will result in the restoration
199 * of the original pre-"locked" data.
201 _swapLockedStoreData();
205 * Close any open connections including cancelling any outstanding
206 * notification requests and releasing any locks.
208 (void) __SCDynamicStoreClose(&thisSession
->store
, TRUE
);
211 * Our send right has already been removed. Remove our
214 mach_port_mod_refs(mach_task_self(),
216 MACH_PORT_RIGHT_RECEIVE
,
220 * Lastly, remove the session entry.
222 removeSession(server
);
237 fprintf(stderr
, "Current sessions:");
238 for (i
= 0; i
< nSessions
; i
++) {
239 serverSessionRef thisSession
= sessions
[i
];
241 if (thisSession
== NULL
) {
245 fprintf(stderr
, " %d", thisSession
->key
);
247 if (thisSession
->store
) {
248 task_t task
= ((SCDynamicStorePrivateRef
)thisSession
->store
)->notifySignalTask
;
250 if (task
!= TASK_NULL
) {
251 fprintf(stderr
, "/%d", task
);
255 fprintf(stderr
, "\n");