#include "configd.h"
#include "configd_server.h"
#include "session.h"
static serverSessionRef *sessions = NULL;
static int nSessions = 0;
__private_extern__
serverSessionRef
getSession(mach_port_t server)
{
int i;
if (server == MACH_PORT_NULL) {
SCLog(TRUE, LOG_NOTICE, CFSTR("Excuse me, why is getSession() being called with an invalid port?"));
return NULL;
}
for (i = 0; i < nSessions; i++) {
serverSessionRef thisSession = sessions[i];
if (thisSession == NULL) {
continue;
} else if (thisSession->key == server) {
return thisSession;
} else if (thisSession->store &&
(((SCDynamicStorePrivateRef)thisSession->store)->notifySignalTask == server)) {
return thisSession;
}
}
return NULL;
}
__private_extern__
serverSessionRef
addSession(mach_port_t server, CFStringRef (*copyDescription)(const void *info))
{
CFMachPortContext context = { 0, NULL, NULL, NULL, NULL };
int n = -1;
if (nSessions <= 0) {
sessions = malloc(sizeof(serverSessionRef));
n = 0;
nSessions = 1;
} else {
int i;
for (i = 0; i < nSessions; i++) {
if (sessions[i] == NULL) {
n = i;
break;
}
}
if (n < 0) {
n = nSessions++;
sessions = reallocf(sessions, ((nSessions) * sizeof(serverSessionRef)));
}
}
sessions[n] = malloc(sizeof(serverSession));
bzero(sessions[n], sizeof(serverSession));
context.info = sessions[n];
context.copyDescription = copyDescription;
if (server == MACH_PORT_NULL) {
(void) mach_port_allocate(mach_task_self(),
MACH_PORT_RIGHT_RECEIVE,
&server);
(void) mach_port_insert_right(mach_task_self(),
server,
server,
MACH_MSG_TYPE_MAKE_SEND);
}
sessions[n]->key = server;
sessions[n]->serverPort = CFMachPortCreateWithPort(NULL,
server,
configdCallback,
&context,
NULL);
sessions[n]->callerEUID = 1;
return sessions[n];
}
__private_extern__
void
removeSession(mach_port_t server)
{
int i;
serverSessionRef thisSession;
CFStringRef sessionKey;
for (i = 0; i < nSessions; i++) {
thisSession = sessions[i];
if (thisSession == NULL) {
continue;
} else if (thisSession->key == server) {
sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), server);
CFDictionaryRemoveValue(sessionData, sessionKey);
CFRelease(sessionKey);
free(thisSession);
sessions[i] = NULL;
return;
}
}
return;
}
__private_extern__
void
cleanupSession(mach_port_t server)
{
int i;
for (i = 0; i < nSessions; i++) {
serverSessionRef thisSession = sessions[i];
if ((thisSession != NULL) && (thisSession->key == server)) {
if (_configd_trace) {
SCTrace(TRUE, _configd_trace, CFSTR("cleanup : %5d\n"), server);
}
if ((storeLocked > 0) &&
((SCDynamicStorePrivateRef)thisSession->store)->locked) {
_swapLockedStoreData();
}
(void) __SCDynamicStoreClose(&thisSession->store, TRUE);
mach_port_mod_refs(mach_task_self(),
thisSession->key,
MACH_PORT_RIGHT_RECEIVE,
-1);
removeSession(server);
return;
}
}
return;
}
__private_extern__
void
listSessions()
{
int i;
fprintf(stderr, "Current sessions:");
for (i = 0; i < nSessions; i++) {
serverSessionRef thisSession = sessions[i];
if (thisSession == NULL) {
continue;
}
fprintf(stderr, " %d", thisSession->key);
if (thisSession->store) {
task_t task = ((SCDynamicStorePrivateRef)thisSession->store)->notifySignalTask;
if (task != TASK_NULL) {
fprintf(stderr, "/%d", task);
}
}
}
fprintf(stderr, "\n");
}