summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--makefile7
-rw-r--r--src/kernel/fat.c4
-rw-r--r--src/user/dirlist/main.c27
-rw-r--r--src/user/include/knob/block.h6
-rw-r--r--src/user/knob/block.c16
5 files changed, 57 insertions, 3 deletions
diff --git a/makefile b/makefile
index 68690e6..6720199 100644
--- a/makefile
+++ b/makefile
@@ -36,7 +36,8 @@ out/fs/bin/%: obj/%.elf
# python3 tools/man-gen.py $< $@
out/fs: out/fs/bin/init out/fs/bin/highway out/fs/bin/meminfo \
- out/fs/bin/terminal out/fs/bin/hello out/fs/bin/mkpopup
+ out/fs/bin/terminal out/fs/bin/hello out/fs/bin/mkpopup \
+ out/fs/bin/dirlist
touch out/fs
cp -r fs-skel/* out/fs/
@@ -117,4 +118,8 @@ obj/hello.elf: obj/hello/hello.ao
obj/mkpopup.elf: obj/mkpopup/main.o obj/popups.so obj/libfont.so \
obj/knob.so obj/c.rto
+ ld -T src/user/runtimes/c/elf.ld $^ -o $@
+
+obj/dirlist.elf: obj/dirlist/main.o obj/libterm.so obj/knob.so \
+ obj/c.rto
ld -T src/user/runtimes/c/elf.ld $^ -o $@ \ No newline at end of file
diff --git a/src/kernel/fat.c b/src/kernel/fat.c
index befc1d8..5ba62cf 100644
--- a/src/kernel/fat.c
+++ b/src/kernel/fat.c
@@ -328,7 +328,7 @@ static uint32_t fat_enumerate_dir(const struct drive *d, const char *path, struc
if (!*path)
return enumerate_root(d, info, max);
- if (!try_load_from_path(d, path)) {
+ if (!try_load_from_path(d, path) || !(cur_dir->attrib & FA_DIRECTORY)) {
d->done(d);
return 0;
}
@@ -397,7 +397,7 @@ static uint32_t fat_n_dir_entries(const struct drive *d, const char *path) {
if (!*path)
return n_root_entries(d);
- if (!try_load_from_path(d, path)) {
+ if (!try_load_from_path(d, path) || !(cur_dir->attrib & FA_DIRECTORY)) {
d->done(d);
return 0;
}
diff --git a/src/user/dirlist/main.c b/src/user/dirlist/main.c
new file mode 100644
index 0000000..64f0ddb
--- /dev/null
+++ b/src/user/dirlist/main.c
@@ -0,0 +1,27 @@
+#include <libterm/terminal.h>
+#include <knob/block.h>
+#include <knob/file.h>
+
+#define MAX_NAME_LEN 15
+#define COLUMN_SEP " - "
+
+void main(const char *path) {
+ uint32_t count;
+ _dir_info_entry_t *entries = get_directory_info(path, &count);
+ if (!entries) {
+ term_addf("Could not list %s\n", path);
+ return;
+ }
+ term_addf("Directory listing for %s:\n\n", *path ? path : "(root)");
+ if (!count) {
+ term_add_sz("(empty)\n");
+ return;
+ }
+ for (_dir_info_entry_t *i = entries; i < entries + count; ++i) {
+ str_trunc_fill(i->name, MAX_NAME_LEN);
+ if (i->is_dir)
+ term_addf_no_ww("%s" COLUMN_SEP "directory\n", i->name);
+ else
+ term_addf_no_ww("%s" COLUMN_SEP "%u bytes\n", i->name, i->size);
+ }
+} \ No newline at end of file
diff --git a/src/user/include/knob/block.h b/src/user/include/knob/block.h
index f77709d..1231a6d 100644
--- a/src/user/include/knob/block.h
+++ b/src/user/include/knob/block.h
@@ -18,4 +18,10 @@ uint32_t strlen(const char *str) __attribute__ ((pure));
bool strequ(const char *a, const char *b) __attribute__ ((pure));
+//if str has length == len, nothing is done
+//if str has length < len, it is right-padded with spaces
+//if str has length > len, the end is replaced with " ..."
+//this replacement happens in place, with no memory allocation
+void str_trunc_fill(char *str, uint32_t len);
+
#endif \ No newline at end of file
diff --git a/src/user/knob/block.c b/src/user/knob/block.c
index 90f79e3..1720f94 100644
--- a/src/user/knob/block.c
+++ b/src/user/knob/block.c
@@ -57,4 +57,20 @@ uint32_t strlen(const char *str) {
++str;
}
return len;
+}
+
+void str_trunc_fill(char *str, uint32_t len) {
+ const uint8_t orig_len = strlen(str);
+ if (orig_len > len) {
+ str[len - 4] = ' ';
+ str[len - 3] = '.';
+ str[len - 2] = '.';
+ str[len - 1] = '.';
+ str[len] = '\0';
+ }
+ else if (orig_len != len) {
+ for (uint8_t j = orig_len; j < len; ++j)
+ str[j] = ' ';
+ str[len] = '\0';
+ }
} \ No newline at end of file