summaryrefslogtreecommitdiffhomepage
path: root/src/cmds/ntux_cmd_stat.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmds/ntux_cmd_stat.c')
-rw-r--r--src/cmds/ntux_cmd_stat.c123
1 files changed, 123 insertions, 0 deletions
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 <ntapi/ntapi.h>
+#include <psxabi/sys_sysapi.h>
+#include <psxabi/sys_stat.h>
+#include <psxabi/sys_errno.h>
+
+#include <psxxfi/xfi_ofd.h>
+#include <psxxfi/xfi_unicode.h>
+
+#include <ntux/ntux.h>
+#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);
+}