diff --git a/base/scripts/rc.tb b/base/scripts/rc.tb index ee9dc56..9e580ad 100644 --- a/base/scripts/rc.tb +++ b/base/scripts/rc.tb @@ -1,2 +1,3 @@ mkalias pctl base:/bin/pctl mkalias tb base:/bin/tb +mkalias fs base:/bin/fs diff --git a/share/sysdefs/ioctl.h b/share/sysdefs/ioctl.h index 3e65e4a..bf588c0 100644 --- a/share/sysdefs/ioctl.h +++ b/share/sysdefs/ioctl.h @@ -30,4 +30,6 @@ typedef struct IoctlStat { int32_t type; } IoctlStat; +typedef int32_t IOH; + #endif // SHARE_SYSDEFS_IOCTL_H_ diff --git a/ulib/string/conv.c b/ulib/string/conv.c index 99c5271..2bd434f 100644 --- a/ulib/string/conv.c +++ b/ulib/string/conv.c @@ -157,3 +157,34 @@ long string_conv_strtol(const char *nptr, char **endptr, int base) *endptr = (char *) (any ? s - 1 : nptr); return (acc); } + +const char *human_size(uint64_t bytes, char *buf, size_t bufsize) { + static const char *units[] = { "B", "KiB", "MiB", "GiB", "TiB", "PiB" }; + int unit = 0; + + // Scale down until value fits nicely + uint64_t rem = 0; + while (bytes >= 1024 && unit < (int)(sizeof(units)/sizeof(units[0])) - 1) { + rem = bytes % 1024; + bytes /= 1024; + unit++; + } + + if (unit == 0) { + // Just bytes + usnprintf(buf, bufsize, "%llu %s", (unsigned long long)bytes, units[unit]); + } else { + // Show one decimal place without using floats + // Multiply remainder by 10 to get first decimal digit + uint64_t frac = (rem * 10 + 512) / 1024; // rounded + if (frac == 10) { // handle carry, e.g. 1023.9 -> 1024.0 + bytes++; + frac = 0; + } + + if (frac > 0) usnprintf(buf, bufsize, "%llu.%llu %s", (unsigned long long)bytes, (unsigned long long)frac, units[unit]); + else usnprintf(buf, bufsize, "%llu %s", (unsigned long long)bytes, units[unit]); + } + + return buf; +} diff --git a/ulib/string/conv.h b/ulib/string/conv.h index 8ad3a90..6bd2518 100644 --- a/ulib/string/conv.h +++ b/ulib/string/conv.h @@ -3,5 +3,6 @@ unsigned long string_conv_strtoul(const char *nptr, char **endptr, int base); long string_conv_strtol(const char *nptr, char **endptr, int base); +const char *human_size(uint64_t bytes, char *buf, size_t bufsize); #endif // ULIB_STRING_CONV_H_ diff --git a/user/fs/.gitignore b/user/fs/.gitignore new file mode 100644 index 0000000..45621e8 --- /dev/null +++ b/user/fs/.gitignore @@ -0,0 +1,2 @@ +*.o +fs diff --git a/user/fs/Makefile b/user/fs/Makefile new file mode 100644 index 0000000..6630816 --- /dev/null +++ b/user/fs/Makefile @@ -0,0 +1,24 @@ +include $(ROOT)/mk/grabsrc.mk +include ../Makefile.inc + +.PHONY: all clean + +TARGET := fs + +LDFLAGS += -L$(ROOT)/ulib -l:libulib.a + +SRCFILES := $(call GRABSRC, .) +CFILES := $(call GET_CFILES, $(SRCFILES)) +OBJ := $(call GET_OBJ, $(SRCFILES)) + +%.o: %.c + $(CC) $(CFLAGS) -c $< -o $@ + +all: $(TARGET) + +$(TARGET): $(OBJ) + $(LD) $^ $(LDFLAGS) -o $@ + echo $$(realpath $(TARGET)) >> $(FILES) + +clean: + rm -f $(OBJ) $(TARGET) diff --git a/user/fs/fetch.c b/user/fs/fetch.c new file mode 100644 index 0000000..631dbf0 --- /dev/null +++ b/user/fs/fetch.c @@ -0,0 +1,35 @@ +#include +#include +#include + +void fs_fetch(void) { + if (argslen() < 2) { + uprintf("fs: Not enough arguments\n"); + return; + } + + char *path = *(args()+1); + + IOH ioh = ioctl(IOCTL_NOHANDLE, IOCTL_OPENF, (uint64_t)path, IOCTL_F_READ, 0); + if (ioh < 0) { + uprintf("fs: could not open %s\n", path); + return; + } + + IoctlStat statbuf; ZERO(&statbuf); + + ioctl(ioh, IOCTL_STAT, (uint64_t)&statbuf, 0, 0); + if (statbuf.type == IOCTLSTAT_FILE) { + uint8_t *buf = umalloc(statbuf.size+1); + string_memset(buf, 0, statbuf.size+1); + + if (ioctl(ioh, IOCTL_READ, (uint64_t)buf, statbuf.size, 0) < 0) { + uprintf("fs: coult not read %s\n", path); + ufree(buf); + ioctl(ioh, IOCTL_CLOSEF, 0, 0, 0); + return; + } + + uprintf("%s", buf); + } +} diff --git a/user/fs/main.c b/user/fs/main.c new file mode 100644 index 0000000..434b5d0 --- /dev/null +++ b/user/fs/main.c @@ -0,0 +1,19 @@ +#include +#include +#include + +extern void fs_fetch(void); + +void main(void) { + if (argslen() == 0) { + return; + } + + char *cmd = args()[0]; + + if (string_strcmp(cmd, "fetch") == 0) { + fs_fetch(); + } else { + uprintf("fs: unknown command %s\n", cmd); + } +} diff --git a/user/pctl/ls.c b/user/pctl/ls.c index de088ad..2152e00 100644 --- a/user/pctl/ls.c +++ b/user/pctl/ls.c @@ -18,38 +18,6 @@ static Arg ARGS[] = { ARG_END(), }; -const char *human_size(uint64_t bytes, char *buf, size_t bufsize) { - static const char *units[] = { "B", "KiB", "MiB", "GiB", "TiB", "PiB" }; - int unit = 0; - - // Scale down until value fits nicely - uint64_t rem = 0; - while (bytes >= 1024 && unit < (int)(sizeof(units)/sizeof(units[0])) - 1) { - rem = bytes % 1024; - bytes /= 1024; - unit++; - } - - if (unit == 0) { - // Just bytes - usnprintf(buf, bufsize, "%llu %s", (unsigned long long)bytes, units[unit]); - } else { - // Show one decimal place without using floats - // Multiply remainder by 10 to get first decimal digit - uint64_t frac = (rem * 10 + 512) / 1024; // rounded - if (frac == 10) { // handle carry, e.g. 1023.9 -> 1024.0 - bytes++; - frac = 0; - } - - if (frac > 0) usnprintf(buf, bufsize, "%llu.%llu %s", (unsigned long long)bytes, (unsigned long long)frac, units[unit]); - else usnprintf(buf, bufsize, "%llu %s", (unsigned long long)bytes, units[unit]); - } - - return buf; -} - - void pctl_ls(void) { int32_t ret; if ((ret = parse_args(SUBCMD_ARGS(), SUBCMD_ARGSLEN(), ARGS)) < 0) {