Blame src/driver/toks_amain.c

8b5736
/*********************************************************/
8b5736
/*  toksvc: a framework-native token broker service      */
8b5736
/*  Copyright (C) 2020  Z. Gilboa                        */
8b5736
/*  Released under GPLv2 and GPLv3; see COPYING.TOKSVC.  */
8b5736
/*********************************************************/
8b5736
8b5736
#include <ntapi/ntapi.h>
8b5736
#include <stdio.h>
8b5736
#include <unistd.h>
8b5736
8b5736
#include <toksvc/toksvc.h>
8b5736
#include "toksvc_init_impl.h"
8b5736
#include "toksvc_driver_impl.h"
8b5736
#include "toksvc_dprintf_impl.h"
8b5736
#include "toksvc_nolibc_impl.h"
b27e56
#include "toksvc_log_impl.h"
8b5736
8b5736
#ifndef TOKS_DRIVER_FLAGS
8b5736
#define TOKS_DRIVER_FLAGS	TOKS_DRIVER_VERBOSITY_ERRORS \
3e9813
				| TOKS_DRIVER_DAEMON_ALWAYS   \
8b5736
				| TOKS_DRIVER_VERBOSITY_USAGE
8b5736
#endif
8b5736
8b5736
static const char vermsg[] = "%s%s%s (git://midipix.org/toksvc): "
8b5736
			     "version %s%d.%d.%d%s.\n"
8b5736
			     "[commit reference: %s%s%s]\n";
8b5736
8b5736
static const char * const toks_ver_color[6] = {
8b5736
		"\x1b[1m\x1b[35m","\x1b[0m",
8b5736
		"\x1b[1m\x1b[32m","\x1b[0m",
8b5736
		"\x1b[1m\x1b[34m","\x1b[0m"
8b5736
};
8b5736
8b5736
static const char * const toks_ver_plain[6] = {
8b5736
		"","",
8b5736
		"","",
8b5736
		"",""
8b5736
};
8b5736
8b5736
static ssize_t toks_version(struct toks_driver_ctx * dctx)
8b5736
{
8b5736
	const struct toks_source_version * verinfo;
8b5736
	const char * const * verclr;
8b5736
8b5736
	verinfo = toks_source_version();
8b5736
	verclr  = isatty(STDOUT_FILENO) ? toks_ver_color : toks_ver_plain;
8b5736
8b5736
	return toks_dprintf(
8b5736
			STDOUT_FILENO,vermsg,
8b5736
			verclr[0],dctx->program,verclr[1],
8b5736
			verclr[2],verinfo->major,verinfo->minor,
8b5736
			verinfo->revision,verclr[3],
8b5736
			verclr[4],verinfo->commit,verclr[5]);
8b5736
}
8b5736
0b7161
static ssize_t toks_output_service_info(struct toks_service_info * svcinfo)
0b7161
{
0b7161
	char guidstr[40];
0b7161
0b7161
	toks_uuid_to_string(
0b7161
		&svcinfo->uuid,
0b7161
		&guidstr);
0b7161
0b7161
	return toks_dprintf(STDOUT_FILENO,
0b7161
		"toks_uuid:%s\n"
0b7161
		"toks_syspid:%d\n"
0b7161
		"toks_systid:%d\n"
0b7161
		"toks_ctrlpid:%d\n"
0b7161
		"toks_csyspid:%d\n"
0b7161
		"toks_allocated:%d\n"
0b7161
		"toks_available:%d\n"
bf3927
		"toks_tused:%d\n"
bf3927
		"toks_tfree:%d\n"
0b7161
		"toks_loglevel:%d\n",
0b7161
		guidstr,
0b7161
		svcinfo->syspid,
0b7161
		svcinfo->systid,
0b7161
		svcinfo->ctrlpid,
0b7161
		svcinfo->csyspid,
0b7161
		svcinfo->allocated,
0b7161
		svcinfo->available,
bf3927
		svcinfo->tused,
bf3927
		svcinfo->tfree,
0b7161
		svcinfo->loglevel);
0b7161
}
0b7161
8b5736
static int toks_exit(struct toks_driver_ctx * dctx, int nerrors)
8b5736
{
8b5736
	toks_free_driver_ctx(dctx);
8b5736
	return nerrors ? 2 : 0;
8b5736
}
8b5736
8b5736
int toks_main(char ** argv, char ** envp)
8b5736
{
8b5736
	int				ret;
b27e56
	int32_t				status;
8b5736
	struct toks_driver_ctx *	dctx;
2dcff1
	struct toks_token_string	toks;
0b7161
	struct toks_service_info	svcinfo;
8b5736
8b5736
	if ((ret = toks_init()))
8b5736
		return ret;
8b5736
8b5736
	if ((ret = toks_get_driver_ctx(argv,envp,TOKS_DRIVER_FLAGS,&dctx)))
8b5736
		return (ret == TOKS_USAGE)
8b5736
			? !argv || !argv[0] || !argv[1]
8b5736
			: 2;
8b5736
8b5736
	if (dctx->cctx->drvflags & TOKS_DRIVER_VERSION)
8b5736
		if ((toks_version(dctx)) < 0)
8b5736
			return toks_exit(dctx,2);
8b5736
2dcff1
	if (dctx->cctx->drvflags & TOKS_DRIVER_ACTION_ACQUIRE) {
b27e56
		ret = (status = toks_client_acquire(dctx))
02451d
			? 2 : 0;
02451d
b27e56
		switch (status) {
b27e56
			case NT_STATUS_SUCCESS:
b27e56
				break;
b27e56
b27e56
			case NT_STATUS_TIMEOUT:
b27e56
				toks_dprintf(STDERR_FILENO,
b27e56
					"%s: the operataion timed out [0x%x].\n",
b27e56
					toks_log_basename(argv[0]),status);
b27e56
				break;
b27e56
b27e56
			default:
b27e56
				toks_dprintf(STDERR_FILENO,
b27e56
					"%s: the operataion has failed [0x%x].\n",
b27e56
					toks_log_basename(argv[0]),status);
b27e56
		}
b27e56
2dcff1
		if (ret == 0) {
2dcff1
			toks_client_token_to_str(dctx,&toks);
2dcff1
			toks_dprintf(STDOUT_FILENO,"%s\n",toks.token);
2dcff1
		}
2dcff1
	}
2dcff1
867b30
	if (dctx->cctx->drvflags & TOKS_DRIVER_ACTION_RELEASE) {
867b30
		ret = toks_client_release(dctx)
867b30
			? 2 : 0;
867b30
867b30
		if (ret == 0) {
867b30
			toks_client_token_to_str(dctx,&toks);
867b30
			toks_dprintf(STDOUT_FILENO,"token %s has been released\n",toks.token);
867b30
		}
867b30
867b30
		if (ret == 2) {
867b30
			toks_dprintf(STDERR_FILENO,"error: invalid token");
867b30
		}
867b30
	}
867b30
520f51
	if (dctx->cctx->drvflags & TOKS_DRIVER_ACTION_ABORT) {
520f51
		ret = (status = toks_service_abort(dctx))
520f51
			? 2 : 0;
520f51
520f51
		switch (status) {
520f51
			case NT_STATUS_SUCCESS:
520f51
				toks_dprintf(STDERR_FILENO,
520f51
					"%s: the server responded with no error.\n",
520f51
					toks_log_basename(argv[0]),status);
520f51
				break;
520f51
520f51
			case NT_STATUS_ACCESS_DENIED:
520f51
				toks_dprintf(STDERR_FILENO,
520f51
					"%s: the abort operataion timed (access denied) [0x%x].\n",
520f51
					toks_log_basename(argv[0]),status);
520f51
				break;
520f51
520f51
			default:
520f51
				toks_dprintf(STDERR_FILENO,
520f51
					"%s: the abort operataion failed ",
520f51
					"(check the system's documentation) [0x%x].",
520f51
					toks_log_basename(argv[0]),status);
520f51
		}
520f51
	}
520f51
bd4f0c
	if (dctx->cctx->drvflags & TOKS_DRIVER_ACTION_NTOKENS_GET) {
bd4f0c
		toks_dprintf(STDOUT_FILENO,
bd4f0c
			"toks_ntokens:%d\n",
bd4f0c
			toks_get_driver_ntokens(dctx));
bd4f0c
	}
bd4f0c
0f44d8
	if (dctx->cctx->drvflags & TOKS_DRIVER_ACTION_NTOKENS_SET) {
0f44d8
		status = toks_service_ioctl(
0f44d8
			dctx,TOKS_IOCTL_SET_TOKEN_COUNT,
0f44d8
			&(uintptr_t){toks_get_driver_ntokens(dctx)},
0f44d8
			0);
0f44d8
0f44d8
		ret = status ? 2 : 0;
0f44d8
0f44d8
		switch (status) {
0f44d8
			case NT_STATUS_SUCCESS:
0f44d8
				toks_dprintf(STDERR_FILENO,
0f44d8
					"%s: the service's ntokens parameter "
0f44d8
					"was successfully set to %d\n",
0f44d8
					toks_log_basename(argv[0]),
0f44d8
					toks_get_driver_ntokens(dctx));
0f44d8
				break;
0f44d8
0f44d8
			default:
0f44d8
				toks_dprintf(STDERR_FILENO,
0f44d8
					"%s: the TOKS_IOCTL_SET_TOKEN_COUNT "
0f44d8
					"ioctl operataion has failed "
0f44d8
					"(check the system's documentation) [0x%x].",
0f44d8
					toks_log_basename(argv[0]),status);
0f44d8
		}
0f44d8
	}
0f44d8
0b7161
	if (dctx->cctx->drvflags & TOKS_DRIVER_ACTION_SVCINFO_GET) {
0b7161
		status = toks_client_query_service(dctx,&svcinfo);
0b7161
		ret    = status ? 2 : 0;
0b7161
0b7161
		switch (status) {
0b7161
			case NT_STATUS_SUCCESS:
0b7161
				toks_output_service_info(&svcinfo);
0b7161
				break;
0b7161
0b7161
			default:
0b7161
				toks_dprintf(STDERR_FILENO,
0b7161
					"%s: the TOKS_IOCTL_GET_SERVICE_INFO "
0b7161
					"ioctl operataion has failed "
0b7161
					"(check the system's documentation) [0x%x].",
0b7161
					toks_log_basename(argv[0]),status);
0b7161
		}
0b7161
	}
0b7161
0b7161
	if (dctx->cctx->drvflags & TOKS_DRIVER_ACTION_SVCINFO_LOG) {
0b7161
		status = toks_service_ioctl(dctx,TOKS_IOCTL_LOG_SERVICE_INFO,0,0);
0b7161
		ret    = status ? 2 : 0;
0b7161
0b7161
		switch (status) {
0b7161
			case NT_STATUS_SUCCESS:
0b7161
				toks_dprintf(STDERR_FILENO,
0b7161
					"%s: a service info log record "
0b7161
					"was successfully created\n",
0b7161
					toks_log_basename(argv[0]));
0b7161
				break;
0b7161
0b7161
			default:
0b7161
				toks_dprintf(STDERR_FILENO,
0b7161
					"%s: the TOKS_IOCTL_LOG_SERVICE_INFO "
0b7161
					"ioctl operataion has failed "
0b7161
					"(check the system's documentation) [0x%x].",
0b7161
					toks_log_basename(argv[0]),status);
0b7161
		}
0b7161
	}
0b7161
618937
	return (dctx->cctx->drvflags & TOKS_DRIVER_MODE_SERVER)
618937
		? NT_STATUS_SERVICE_NOTIFICATION
618937
		: toks_exit(dctx,ret);
8b5736
}