]> git.saurik.com Git - apple/configd.git/blob - configd.tproj/session.c
configd-24.tar.gz
[apple/configd.git] / configd.tproj / session.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 #include "configd.h"
24 #include "configd_server.h"
25 #include "session.h"
26
27 /* information maintained for each active session */
28 static serverSessionRef *sessions = NULL;
29 static int nSessions = 0;
30
31
32 serverSessionRef
33 getSession(mach_port_t server)
34 {
35 int i;
36
37 if (server == MACH_PORT_NULL) {
38 SCDLog(LOG_NOTICE, CFSTR("Excuse me, why is getSession() being called with an invalid port?"));
39 return NULL;
40 }
41
42 if (nSessions > 0) {
43 for (i=0; i<nSessions; i++) {
44 serverSessionRef thisSession = sessions[i];
45
46 if (thisSession == NULL) {
47 /* found an empty slot, skip it */
48 continue;
49 } else if (thisSession->key == server) {
50 return thisSession; /* we've seen this server before */
51 } else if ((thisSession->session != NULL) &&
52 (((SCDSessionPrivateRef)thisSession->session)->notifySignalTask == server)) {
53 return thisSession;
54 }
55 }
56 }
57
58 /* no sessions available */
59 return NULL;
60 }
61
62
63 serverSessionRef
64 addSession(CFMachPortRef server)
65 {
66 int i;
67 int n = -1;
68
69 if (nSessions <= 0) {
70 /* new session (actually, the first) found */
71 sessions = malloc(sizeof(serverSessionRef));
72 n = 0;
73 nSessions = 1;
74 } else {
75 for (i=0; i<nSessions; i++) {
76 if (sessions[i] == NULL) {
77 /* found an empty slot, use it */
78 n = i;
79 }
80 }
81 /* new session identified */
82 if (n < 0) {
83 /* no empty slots, add one to the list */
84 n = nSessions++;
85 sessions = realloc(sessions, ((nSessions) * sizeof(serverSessionRef)));
86 }
87 }
88
89 SCDLog(LOG_DEBUG, CFSTR("Allocating new session for port %d"), CFMachPortGetPort(server));
90 sessions[n] = malloc(sizeof(serverSession));
91 sessions[n]->key = CFMachPortGetPort(server);
92 sessions[n]->serverPort = server;
93 sessions[n]->serverRunLoopSource = NULL;
94 sessions[n]->session = NULL;
95 sessions[n]->callerEUID = 1; /* not "root" */
96 sessions[n]->callerEGID = 1; /* not "wheel" */
97
98 return sessions[n];
99 }
100
101
102 void
103 removeSession(mach_port_t server)
104 {
105 int i;
106 serverSessionRef thisSession;
107 CFStringRef sessionKey;
108
109 for (i=0; i<nSessions; i++) {
110 thisSession = sessions[i];
111
112 if (thisSession == NULL) {
113 /* found an empty slot, skip it */
114 continue;
115 } else if (thisSession->key == server) {
116 /*
117 * We don't need any remaining information in the
118 * sessionData dictionary, remove it.
119 */
120 sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), server);
121 CFDictionaryRemoveValue(sessionData, sessionKey);
122 CFRelease(sessionKey);
123
124 /*
125 * Lastly, get rid of the per-session structure.
126 */
127 free(thisSession);
128 sessions[i] = NULL;
129
130 return;
131 }
132 }
133
134 return;
135 }
136
137
138 void
139 cleanupSession(mach_port_t server)
140 {
141 int i;
142
143 for (i=0; i<nSessions; i++) {
144 serverSessionRef thisSession = sessions[i];
145
146 if ((thisSession != NULL) && (thisSession->key == server)) {
147 /*
148 * session entry still exists.
149 */
150
151 /*
152 * Ensure that any changes made while we held the "lock"
153 * are discarded.
154 */
155 if (SCDOptionGet(NULL, kSCDOptionIsLocked) &&
156 SCDOptionGet(thisSession->session, kSCDOptionIsLocked)) {
157 /*
158 * swap cache and associated data which, after
159 * being closed, will result in the restoration
160 * of the original pre-"locked" data.
161 */
162 _swapLockedCacheData();
163 }
164
165 /*
166 * Close any open connections including cancelling any outstanding
167 * notification requests and releasing any locks.
168 */
169 (void) _SCDClose(&thisSession->session);
170
171 /*
172 * Lastly, remove the session entry.
173 */
174 removeSession(server);
175
176 return;
177 }
178 }
179 return;
180 }
181
182
183 void
184 listSessions()
185 {
186 int i;
187
188 fprintf(stderr, "Current sessions:");
189 for (i=0; i<nSessions; i++) {
190 serverSessionRef thisSession = sessions[i];
191
192 if (thisSession == NULL) {
193 continue;
194 }
195
196 fprintf(stderr, " %d", thisSession->key);
197
198 if (thisSession->session != NULL) {
199 task_t task = ((SCDSessionPrivateRef)thisSession->session)->notifySignalTask;
200
201 if (task != TASK_NULL) {
202 fprintf(stderr, "/%d", task);
203 }
204 }
205 }
206 fprintf(stderr, "\n");
207 }
208