/*********************************************************/
/* toksvc: a framework-native token broker service */
/* Copyright (C) 2020 SysDeer Technologies, LLC */
/* Released under GPLv2 and GPLv3; see COPYING.TOKSVC. */
/*********************************************************/
#include <ntapi/ntapi.h>
#include <stdio.h>
extern const ntapi_vtbl * toks_ntapi;
int toks_sprintf(char * str, const char * fmt, ...)
{
int ret;
va_list ap;
va_start(ap, fmt);
ret = toks_ntapi->vsprintf(str, fmt, ap);
va_end(ap);
return ret;
}
int toks_snprintf(char * str, size_t n, const char * fmt, ...)
{
int ret;
va_list ap;
va_start(ap, fmt);
ret = toks_ntapi->vsnprintf(str, n, fmt, ap);
va_end(ap);
return ret;
}
int toks_isatty(int fildes)
{
nt_runtime_data * rtdata;
if ((toks_ntapi->tt_get_runtime_data(&rtdata,0)))
return 0;
if (fildes == 0)
return (rtdata->stdin_type == NT_FILE_TYPE_PTY);
else if (fildes == 1)
return (rtdata->stdout_type == NT_FILE_TYPE_PTY);
else if (fildes == 2)
return (rtdata->stderr_type == NT_FILE_TYPE_PTY);
else
return 0;
}
int toks_write(int fd, const void * buf, size_t size)
{
int32_t status;
nt_runtime_data * rtdata;
ntapi_zw_write_file * iofn;
void * hio;
void * hevent;
int fdtype;
nt_iosb iosb;
/* size */
if (size >= 0x80000000)
return NT_STATUS_INVALID_PARAMETER;
/* rtdata */
if (toks_ntapi->tt_get_runtime_data(&rtdata,0))
return NT_STATUS_REINITIALIZATION_NEEDED;
/* hio, io type */
if (fd == STDIN_FILENO) {
hio = rtdata->hstdin;
fdtype = rtdata->stdin_type;
} else if (fd == STDOUT_FILENO) {
hio = rtdata->hstdout;
fdtype = rtdata->stdout_type;
} else if (fd == STDERR_FILENO) {
hio = rtdata->hstderr;
fdtype = rtdata->stderr_type;
} else {
return NT_STATUS_INVALID_PARAMETER;
}
if (!hio)
return NT_STATUS_INVALID_HANDLE;
/* iofn */
iofn = (fdtype == NT_FILE_TYPE_PTY)
? (ntapi_zw_write_file *)toks_ntapi->pty_write
: toks_ntapi->zw_write_file;
/* hevent */
if ((status = toks_ntapi->tt_create_private_event(
&hevent,
NT_NOTIFICATION_EVENT,
NT_EVENT_NOT_SIGNALED)))
return status;
/* iowrite */
iosb.status = NT_STATUS_PENDING;
status = iofn(
hio,hevent,
0,0,&iosb,
(void *)buf,size,
0,0);
/* wait */
if (status == NT_STATUS_PENDING)
toks_ntapi->zw_wait_for_single_object(
hevent,0,0);
/* hevent */
toks_ntapi->zw_close(hevent);
/* ret */
switch (iosb.status) {
case NT_STATUS_SUCCESS:
return iosb.info;
default:
return (iosb.status < 0)
? iosb.status
: -iosb.status;
}
}