d2175fc3f562d7b657a8fcc0be1dd68a792666a4
[apple/configd.git] / configd.tproj / session.c
1 /*
2 * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25
26 /*
27 * Modification History
28 *
29 * June 1, 2001 Allan Nathanson <ajn@apple.com>
30 * - public API conversion
31 *
32 * March 24, 2000 Allan Nathanson <ajn@apple.com>
33 * - initial revision
34 */
35
36 #include "configd.h"
37 #include "configd_server.h"
38 #include "session.h"
39
40 /* information maintained for each active session */
41 static serverSessionRef *sessions = NULL;
42 static int nSessions = 0;
43
44
45 __private_extern__
46 serverSessionRef
47 getSession(mach_port_t server)
48 {
49 int i;
50
51 if (server == MACH_PORT_NULL) {
52 SCLog(_configd_verbose, LOG_NOTICE, CFSTR("Excuse me, why is getSession() being called with an invalid port?"));
53 return NULL;
54 }
55
56 for (i = 0; i < nSessions; i++) {
57 serverSessionRef thisSession = sessions[i];
58
59 if (thisSession == NULL) {
60 /* found an empty slot, skip it */
61 continue;
62 } else if (thisSession->key == server) {
63 return thisSession; /* we've seen this server before */
64 } else if (thisSession->store &&
65 (((SCDynamicStorePrivateRef)thisSession->store)->notifySignalTask == server)) {
66 return thisSession;
67 }
68 }
69
70 /* no sessions available */
71 return NULL;
72 }
73
74
75 __private_extern__
76 serverSessionRef
77 addSession(CFMachPortRef server)
78 {
79 int i;
80 int n = -1;
81
82 if (nSessions <= 0) {
83 /* new session (actually, the first) found */
84 sessions = malloc(sizeof(serverSessionRef));
85 n = 0;
86 nSessions = 1;
87 } else {
88 for (i = 0; i < nSessions; i++) {
89 if (sessions[i] == NULL) {
90 /* found an empty slot, use it */
91 n = i;
92 }
93 }
94 /* new session identified */
95 if (n < 0) {
96 /* no empty slots, add one to the list */
97 n = nSessions++;
98 sessions = realloc(sessions, ((nSessions) * sizeof(serverSessionRef)));
99 }
100 }
101
102 SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Allocating new session for port %d"), CFMachPortGetPort(server));
103 sessions[n] = malloc(sizeof(serverSession));
104 sessions[n]->key = CFMachPortGetPort(server);
105 sessions[n]->serverPort = server;
106 sessions[n]->serverRunLoopSource = NULL;
107 sessions[n]->store = NULL;
108 sessions[n]->callerEUID = 1; /* not "root" */
109 sessions[n]->callerEGID = 1; /* not "wheel" */
110
111 return sessions[n];
112 }
113
114
115 __private_extern__
116 void
117 removeSession(mach_port_t server)
118 {
119 int i;
120 serverSessionRef thisSession;
121 CFStringRef sessionKey;
122
123 for (i = 0; i < nSessions; i++) {
124 thisSession = sessions[i];
125
126 if (thisSession == NULL) {
127 /* found an empty slot, skip it */
128 continue;
129 } else if (thisSession->key == server) {
130 /*
131 * We don't need any remaining information in the
132 * sessionData dictionary, remove it.
133 */
134 sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), server);
135 CFDictionaryRemoveValue(sessionData, sessionKey);
136 CFRelease(sessionKey);
137
138 /*
139 * Lastly, get rid of the per-session structure.
140 */
141 free(thisSession);
142 sessions[i] = NULL;
143
144 return;
145 }
146 }
147
148 return;
149 }
150
151
152 __private_extern__
153 void
154 cleanupSession(mach_port_t server)
155 {
156 int i;
157
158 for (i = 0; i < nSessions; i++) {
159 serverSessionRef thisSession = sessions[i];
160
161 if ((thisSession != NULL) && (thisSession->key == server)) {
162 /*
163 * session entry still exists.
164 */
165
166 if (_configd_trace) {
167 SCTrace(TRUE, _configd_trace, CFSTR("cleanup : %5d\n"), server);
168 }
169
170 /*
171 * Ensure that any changes made while we held the "lock"
172 * are discarded.
173 */
174 if ((storeLocked > 0) &&
175 ((SCDynamicStorePrivateRef)thisSession->store)->locked) {
176 /*
177 * swap store and associated data which, after
178 * being closed, will result in the restoration
179 * of the original pre-"locked" data.
180 */
181 _swapLockedStoreData();
182 }
183
184 /*
185 * Close any open connections including cancelling any outstanding
186 * notification requests and releasing any locks.
187 */
188 (void) __SCDynamicStoreClose(&thisSession->store, TRUE);
189
190 /*
191 * Lastly, remove the session entry.
192 */
193 removeSession(server);
194
195 return;
196 }
197 }
198 return;
199 }
200
201
202 __private_extern__
203 void
204 listSessions()
205 {
206 int i;
207
208 fprintf(stderr, "Current sessions:");
209 for (i = 0; i < nSessions; i++) {
210 serverSessionRef thisSession = sessions[i];
211
212 if (thisSession == NULL) {
213 continue;
214 }
215
216 fprintf(stderr, " %d", thisSession->key);
217
218 if (thisSession->store) {
219 task_t task = ((SCDynamicStorePrivateRef)thisSession->store)->notifySignalTask;
220
221 if (task != TASK_NULL) {
222 fprintf(stderr, "/%d", task);
223 }
224 }
225 }
226 fprintf(stderr, "\n");
227 }
228