summaryrefslogtreecommitdiff
path: root/src/user/ls.cc
diff options
context:
space:
mode:
authorRichard Qin <richard.qin.x@gmail.com>2026-01-04 14:12:24 +0800
committerRichard Qin <richard.qin.x@gmail.com>2026-01-04 14:12:24 +0800
commita64d25c07b31d57f8706073e11cd774d0880d6dd (patch)
treea4bbae6cff94fa69eea30db865267b211eb4c86b /src/user/ls.cc
parent210025560c80b48af4875af199f183ad709e3bf0 (diff)
parentd3cf3f08d1343d6b265516d5a79ce2d197b59d26 (diff)
downloadlume-a64d25c07b31d57f8706073e11cd774d0880d6dd.tar.gz
lume-a64d25c07b31d57f8706073e11cd774d0880d6dd.tar.xz
Merge pull request #5 from Richard-Qin-001/dev/file-system
feat(file-system): implement read and write FAT32 File System and basic shell
Diffstat (limited to 'src/user/ls.cc')
-rw-r--r--src/user/ls.cc112
1 files changed, 112 insertions, 0 deletions
diff --git a/src/user/ls.cc b/src/user/ls.cc
new file mode 100644
index 0000000..e472578
--- /dev/null
+++ b/src/user/ls.cc
@@ -0,0 +1,112 @@
+#include "ulib/stdio.h"
+#include "ulib/stdlib.h"
+#include "ulib/string.h"
+#include "user/user.h"
+#include "common/fcntl.h"
+
+
+struct FAT32_DirEnt
+{
+ char name[11];
+ uint8 attr;
+ uint8 lcase;
+ uint8 ctime_cs;
+ uint16 ctime;
+ uint16 cdate;
+ uint16 adate;
+ uint16 fstClusHI;
+ uint16 wtime;
+ uint16 wdate;
+ uint16 fstClusLO;
+ uint32 fileSize;
+} __attribute__((packed));
+
+#define ATTR_DIRECTORY 0x10
+#define ATTR_LONG_NAME 0x0F
+
+void fmt_name(char *dst, const char *src)
+{
+ int i;
+ char *d = dst;
+
+ for (i = 0; i < 8; i++)
+ {
+ if (src[i] == ' ')
+ break;
+ *d++ = src[i];
+ }
+
+ if (src[8] != ' ')
+ {
+ *d++ = '.';
+ for (i = 8; i < 11; i++)
+ {
+ if (src[i] == ' ')
+ break;
+ *d++ = src[i];
+ }
+ }
+ *d = 0;
+
+ for (d = dst; *d; d++)
+ {
+ if (*d >= 'A' && *d <= 'Z')
+ *d += 32;
+ }
+}
+
+void ls(const char *path)
+{
+ int fd;
+ struct FAT32_DirEnt de;
+ char name_buf[16];
+
+ if ((fd = open(path, O_RDONLY)) < 0)
+ {
+ printf("ls: cannot open %s\n", path);
+ return;
+ }
+
+ while (read(fd, &de, sizeof(de)) == sizeof(de))
+ {
+ if (de.name[0] == 0)
+ {
+ break;
+ }
+
+ if ((unsigned char)de.name[0] == 0xE5)
+ {
+ continue;
+ }
+
+ if ((de.attr & ATTR_LONG_NAME) == ATTR_LONG_NAME)
+ {
+ continue;
+ }
+
+ fmt_name(name_buf, de.name);
+
+ printf("%s %d\t%s\n",
+ (de.attr & ATTR_DIRECTORY) ? "<DIR>" : " ",
+ de.fileSize,
+ name_buf);
+ }
+
+ close(fd);
+}
+
+int main(int argc, char *argv[])
+{
+ if (argc < 2)
+ {
+ ls(".");
+ }
+ else
+ {
+ for (int i = 1; i < argc; i++)
+ {
+ ls(argv[i]);
+ }
+ }
+ exit(0);
+} \ No newline at end of file