#include <TargetConditionals.h>
#include <sysexits.h>
#include <unistd.h>
#include <sys/types.h>
#include <servers/bootstrap.h>
#include "configd.h"
#include "configd_server.h"
#include "session.h"
extern struct mig_subsystem _config_subsystem;
__private_extern__
void
server_mach_channel_handler(void *context, dispatch_mach_reason_t reason,
dispatch_mach_msg_t message,
mach_error_t error)
{
#pragma unused(error)
bool ok;
serverSessionRef session = (serverSessionRef)context;
static const struct mig_subsystem * const subsystems[] = {
(mig_subsystem_t)&_config_subsystem,
};
switch (reason) {
case DISPATCH_MACH_MESSAGE_RECEIVED:
ok = dispatch_mach_mig_demux(context, subsystems, 1, message);
if (ok) {
pushNotifications();
} else {
mach_msg_destroy(dispatch_mach_msg_get_msg(message, NULL));
}
break;
case DISPATCH_MACH_NO_SENDERS:
__MACH_PORT_DEBUG(TRUE, "*** server_mach_channel_handler DISPATCH_MACH_NO_SENDERS", session->key);
closeSession(session);
break;
case DISPATCH_MACH_CANCELED:
__MACH_PORT_DEBUG(TRUE, "*** server_mach_channel_handler DISPATCH_MACH_CANCELED", session->key);
cleanupSession(session);
break;
default:
break;
}
return;
}
__private_extern__
dispatch_workloop_t
server_queue(void)
{
static dispatch_once_t once;
static dispatch_workloop_t workloop;
dispatch_once(&once, ^{
workloop = dispatch_workloop_create_inactive("configd/SCDynamicStore");
dispatch_set_qos_class_fallback(workloop, QOS_CLASS_UTILITY);
dispatch_activate(workloop);
});
return workloop;
}
__private_extern__
void
server_init()
{
char *service_name;
mach_port_t service_port = MACH_PORT_NULL;
kern_return_t status;
service_name = getenv("SCD_SERVER");
if (service_name == NULL) {
service_name = SCD_SERVER;
}
status = bootstrap_check_in(bootstrap_port, service_name, &service_port);
switch (status) {
case BOOTSTRAP_SUCCESS :
break;
case BOOTSTRAP_NOT_PRIVILEGED :
SC_log(LOG_ERR, "'%s' server already starting", service_name);
exit (EX_UNAVAILABLE);
case BOOTSTRAP_SERVICE_ACTIVE :
SC_log(LOG_ERR, "'%s' server already active", service_name);
exit (EX_UNAVAILABLE);
default :
SC_log(LOG_ERR, "server_init bootstrap_check_in(..., '%s', ...) failed: %s",
service_name,
bootstrap_strerror(status));
exit (EX_UNAVAILABLE);
}
addServer(service_port);
return;
}