Blame src/toksvc.c

f9f1df
/*********************************************************/
f9f1df
/*  toksvc: a framework-native token broker service      */
f9f1df
/*  Copyright (C) 2020  Z. Gilboa                        */
f9f1df
/*  Released under GPLv2 and GPLv3; see COPYING.TOKSVC.  */
f9f1df
/*********************************************************/
f9f1df
f9f1df
#include <pemagine/pemagine.h>
f9f1df
#include <ntapi/ntapi.h>
f9f1df
#include <toksvc/toksvc.h>
f9f1df
#include "toksvc_init_impl.h"
f9f1df
#include "toksvc_driver_impl.h"
f9f1df
f9f1df
static const nt_guid toksvc_daemon_guid = TOKS_PORT_GUID_DAEMON;
f9f1df
f9f1df
static void toksvc_exit(int code)
f9f1df
{
618937
	/* server mode? */
618937
	if (code == NT_STATUS_SERVICE_NOTIFICATION)
618937
		ntapi->zw_terminate_thread(
618937
			NT_CURRENT_THREAD_HANDLE,
618937
			code);
618937
f9f1df
	/* posix exit code? */
f9f1df
	if ((code >= 0) && (code <= 0xff))
f9f1df
		code <<= 8;
f9f1df
f9f1df
	ntapi->zw_terminate_process(
f9f1df
		NT_CURRENT_PROCESS_HANDLE,
f9f1df
		code);
f9f1df
}
f9f1df
f9f1df
static int toksvc_dbg_helper(int32_t status)
f9f1df
{
f9f1df
	return status ? -1 : 0;
f9f1df
}
f9f1df
f9f1df
static int toksvc_dbg_init(char ** argv)
f9f1df
{
f9f1df
	if (argv[1] && !(ntapi->tt_strcmp_multibyte(argv[1],"--wait")))
f9f1df
		return toksvc_dbg_helper(
f9f1df
			ntapi->tt_wait_for_dummy_event());
f9f1df
	return 0;
f9f1df
}
f9f1df
f9f1df
static int32_t toksvc_start(char ** argv, char ** envp)
f9f1df
{
f9f1df
	int32_t				status;
f9f1df
	nt_runtime_data *		rtdata;
f9f1df
	nt_port_attr			port_attr;
f9f1df
        nt_pty_client_info		client_info;
f9f1df
	nt_iosb				iosb;
f9f1df
f9f1df
	/* rtdata */
f9f1df
	if ((status = ntapi->tt_get_runtime_data(&rtdata,0)))
f9f1df
		return status;
f9f1df
f9f1df
	if (rtdata->argv) {
f9f1df
		argv = rtdata->argv;
f9f1df
		envp = rtdata->envp;
f9f1df
	}
f9f1df
f9f1df
	/* early debug (optional) */
f9f1df
	toksvc_dbg_init(argv);
f9f1df
f9f1df
	/* daemon */
f9f1df
	if (!(ntapi->tt_guid_compare(
f9f1df
			&rtdata->srv_guid,
f9f1df
			&(nt_guid)NT_PORT_GUID_DEFAULT)))
f9f1df
		ntapi->tt_guid_copy(
f9f1df
			&rtdata->srv_guid,
f9f1df
			&toksvc_daemon_guid);
f9f1df
f9f1df
	/* no tty session? */
32933a
	if (!rtdata->tty_keys[0]) {
32933a
		if (rtdata->hready)
32933a
			if ((status = ntapi->zw_set_event(rtdata->hready,0)))
32933a
				return status;
32933a
f9f1df
		return toks_main(argv,envp);
32933a
	}
f9f1df
f9f1df
	/* tty */
f9f1df
	ntapi->tt_aligned_block_memset(
f9f1df
		&port_attr,0,sizeof(port_attr));
f9f1df
f9f1df
	port_attr.type		= NT_PORT_TYPE_SUBSYSTEM;
f9f1df
	port_attr.subtype	= NT_PORT_SUBTYPE_DEFAULT;
f9f1df
f9f1df
	port_attr.keys.key[0]	= rtdata->tty_keys[0];
f9f1df
	port_attr.keys.key[1]	= rtdata->tty_keys[1];
f9f1df
	port_attr.keys.key[2]	= rtdata->tty_keys[2];
f9f1df
	port_attr.keys.key[3]	= rtdata->tty_keys[3];
f9f1df
	port_attr.keys.key[4]	= rtdata->tty_keys[4];
f9f1df
	port_attr.keys.key[5]	= rtdata->tty_keys[5];
f9f1df
f9f1df
	ntapi->tt_guid_copy(
f9f1df
		&port_attr.guid,
f9f1df
		&rtdata->tty_guid);
f9f1df
f9f1df
	if ((status = ntapi->tty_join_session(
f9f1df
			&rtdata->hsession,0,
f9f1df
			&port_attr,
f9f1df
			NT_TTY_SESSION_PRIMARY)))
f9f1df
		return status;
f9f1df
f9f1df
	/* pty */
f9f1df
	if ((status = ntapi->pty_inherit_runtime_ctty(
f9f1df
			rtdata->hsession,
f9f1df
			rtdata)))
f9f1df
		return status;
f9f1df
f9f1df
	/* ctty identification */
f9f1df
	if (rtdata->hctty) {
f9f1df
		client_info.any[0] = 0;
f9f1df
		client_info.any[1] = 0;
f9f1df
		client_info.any[2] = 0;
f9f1df
		client_info.any[3] = 0;
f9f1df
f9f1df
		if ((status = ntapi->pty_set(
f9f1df
				rtdata->hctty,&iosb,
f9f1df
				&client_info,sizeof(client_info),
f9f1df
				NT_PTY_CLIENT_INFORMATION)))
f9f1df
			return status;
f9f1df
	}
f9f1df
f9f1df
	/* ready */
f9f1df
	if (rtdata->hready)
f9f1df
		if ((status = ntapi->zw_set_event(rtdata->hready,0)))
f9f1df
			return status;
f9f1df
f9f1df
	/* main */
f9f1df
	return toks_main(argv,envp);
f9f1df
}
f9f1df
f9f1df
static int __stdcall toksvc_daemon_entry_point(void * hswap)
f9f1df
{
f9f1df
	int32_t		status;
f9f1df
	int		argc;
f9f1df
	char **		argv;
f9f1df
	char **		envp;
f9f1df
f9f1df
	ntapi->zw_set_event(hswap,0);
f9f1df
	ntapi->zw_close(hswap);
f9f1df
f9f1df
	if ((status = ntapi->tt_get_argv_envp_utf8(
f9f1df
			&argc,&argv,&envp,
f9f1df
			0,0,0)))
f9f1df
		toksvc_exit(status);
f9f1df
f9f1df
	toksvc_exit(toksvc_start(argv,envp));
f9f1df
f9f1df
	return NT_STATUS_INTERNAL_ERROR;
f9f1df
}
f9f1df
f9f1df
int toksvc_entry_point(void)
f9f1df
{
f9f1df
	int32_t			status;
f9f1df
	nt_thread_params	params;
f9f1df
	void *			hswap;
f9f1df
f9f1df
	if ((status = toks_init()))
f9f1df
		return status;
f9f1df
f9f1df
	if ((status = ntapi->tt_create_private_event(
f9f1df
			&hswap,
f9f1df
			NT_NOTIFICATION_EVENT,
f9f1df
			NT_EVENT_NOT_SIGNALED)))
f9f1df
		return status;
f9f1df
f9f1df
	ntapi->tt_aligned_block_memset(
f9f1df
		&params,0,sizeof(params));
f9f1df
f9f1df
	params.hprocess		  = NT_CURRENT_PROCESS_HANDLE;
f9f1df
	params.start		  = toksvc_daemon_entry_point;
f9f1df
	params.arg                = hswap;
f9f1df
	params.stack_size_commit  = 128 * 1024;
f9f1df
	params.stack_size_reserve = 128 * 1024;
f9f1df
	params.creation_flags	  = NT_CREATE_LOCAL_THREAD;
f9f1df
f9f1df
	if ((status = ntapi->tt_create_thread(&params)))
f9f1df
		toksvc_exit(status);
f9f1df
f9f1df
	ntapi->zw_wait_for_single_object(
f9f1df
		hswap,NT_SYNC_NON_ALERTABLE,0);
f9f1df
f9f1df
	ntapi->zw_close(
f9f1df
		params.hthread);
f9f1df
f9f1df
	ntapi->zw_terminate_thread(
f9f1df
		NT_CURRENT_THREAD_HANDLE,
f9f1df
		NT_STATUS_SUCCESS);
f9f1df
f9f1df
	return NT_STATUS_INTERNAL_ERROR;
f9f1df
}