diff --git a/include/ntux/ntux.h b/include/ntux/ntux.h index 12cba1e..d612e6e 100644 --- a/include/ntux/ntux.h +++ b/include/ntux/ntux.h @@ -102,6 +102,9 @@ ntux_api int ntux_get_driver_ctx (char ** argv, char ** envp, uint32_t flags, s ntux_api int ntux_create_driver_ctx (const struct ntux_common_ctx *, struct ntux_driver_ctx **); ntux_api void ntux_free_driver_ctx (struct ntux_driver_ctx *); +/* cmd api */ +ntux_api int ntux_cmd_stat (const struct ntux_driver_ctx *, const char *); + /* utility api */ ntux_api int ntux_main (int, char **, char **); ntux_api int ntux_output_error_vector (const struct ntux_driver_ctx *); diff --git a/project/common.mk b/project/common.mk index 1be73a6..4790bc0 100644 --- a/project/common.mk +++ b/project/common.mk @@ -11,6 +11,9 @@ INTERNAL_SRCS = \ src/internal/ntux_ntaio_impl.c \ src/internal/ntux_strerr_impl.c \ +CMD_SRCS = \ + src/cmds/ntux_cmd_stat.c \ + OUTPUT_SRCS = \ src/output/ntux_output_error.c \ @@ -20,4 +23,5 @@ APP_SRCS = \ COMMON_SRCS = \ $(DRIVER_SRCS) \ $(INTERNAL_SRCS) \ + $(CMD_SRCS) \ $(OUTPUT_SRCS) \ diff --git a/src/cmds/ntux_cmd_stat.c b/src/cmds/ntux_cmd_stat.c new file mode 100644 index 0000000..38076b3 --- /dev/null +++ b/src/cmds/ntux_cmd_stat.c @@ -0,0 +1,123 @@ +/***********************************************************/ +/* ntux: native translation und extension */ +/* Copyright (C) 2016--2018 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.NTUX. */ +/***********************************************************/ + +#include +#include +#include +#include + +#include +#include + +#include +#include "ntux_driver_impl.h" +#include "ntux_nolibc_impl.h" +#include "ntux_errinfo_impl.h" + +static int ntux_cmd_stat_ret(int fd, struct __ofd * ofd, void * buf, void * sbuf, int ret) +{ + if (fd >= 0) + __sys_close(fd); + + if (ofd) + __xfi_ofd_ref_dec(ofd); + + if (buf) + ntux_free(buf); + + if (sbuf) + ntux_free(sbuf); + + return ret; +} + +int ntux_cmd_stat(const struct ntux_driver_ctx * dctx, const char * dunit) +{ + intptr_t ret; + int32_t status; + const unsigned char * unit; + nt_stat * nstat; + struct __stat st; + char * str; + int fd = -1; + struct __ofd * ofd = 0; + void * buf = 0; + void * sbuf = 0; + const size_t bufsize = 0x10000; + + /* init */ + ntux_driver_set_ectx( + dctx,0,dunit); + + unit = (const unsigned char *)dunit; + + /* open */ + if ((ret = __sys_open(unit,0,0)) < 0) + if (ntux_errno_set(dctx,ret)) + return ntux_cmd_stat_ret( + fd,ofd,buf,sbuf, + NTUX_SYSTEM_ERROR(dctx)); + + fd = ret; + + /* ofd */ + if (!(ofd = __xfi_ofd_ref_inc(fd))) + return ntux_cmd_stat_ret( + fd,ofd,buf,sbuf, + NTUX_CUSTOM_ERROR( + dctx, + NTUX_ERR_FLOW_ERROR)); + + /* fstat */ + if ((ret = __sys_fstat(fd,&st))) + if (ntux_errno_set(dctx,ret)) + return ntux_cmd_stat_ret( + fd,ofd,buf,sbuf, + NTUX_SYSTEM_ERROR(dctx)); + + /* buffers */ + if (!(buf = ntux_calloc(1,bufsize))) + if (ntux_errno_set(dctx,ENOMEM)) + return ntux_cmd_stat_ret( + fd,ofd,buf,sbuf, + NTUX_SYSTEM_ERROR(dctx)); + + if (!(sbuf = ntux_calloc(1,bufsize))) + if (ntux_errno_set(dctx,ENOMEM)) + return ntux_cmd_stat_ret( + fd,ofd,buf,sbuf, + NTUX_SYSTEM_ERROR(dctx)); + + nstat = (nt_stat *)sbuf; + + /* stat */ + if ((status = ntapi->tt_stat( + ofd->info.hfile, + nstat,bufsize, + buf,bufsize, + NT_STAT_DEV_NAME_COPY))) + return ntux_cmd_stat_ret( + fd,ofd,buf,sbuf, + NTUX_NATIVE_ERROR(dctx,status)); + + /* native name */ + str = (char *)buf; + + if ((status = __xfi_strconv_utf16_to_utf8( + nstat->dev_name, + str,bufsize,0))) + return ntux_cmd_stat_ret( + fd,ofd,buf,sbuf, + NTUX_NATIVE_ERROR(dctx,status)); + + ntux_fprintf(stdout,"fname: %s\n",str); + + /* inode */ + ntux_fprintf(stdout,"inode: 0x%p (%lld)\n",st.st_ino,st.st_ino); + + /* all done */ + return ntux_cmd_stat_ret(fd,ofd,buf,sbuf,0); +} diff --git a/src/driver/ntux_amain.c b/src/driver/ntux_amain.c index 11741c9..7749f63 100644 --- a/src/driver/ntux_amain.c +++ b/src/driver/ntux_amain.c @@ -51,8 +51,8 @@ static void ntux_perform_unit_actions( const struct ntux_driver_ctx * dctx, const char * unit) { - (void)dctx; - (void)unit; + if (dctx->cctx->cmd == NTUX_CMD_STAT) + ntux_cmd_stat(dctx,unit); } static int ntux_exit(struct ntux_driver_ctx * dctx, int ret)