fxBoot/src/builtin/ls.c

90 lines
2.1 KiB
C

//---
// builtin:ls - list directory contents
//---
#include "fxBoot/builtin.h"
#include "fxBoot/terminal.h"
#include "fxBoot/fs/smemfs.h"
#include <gint/std/string.h>
#include <gint/bfile.h>
static void smemfs_generate_path(volatile char **path,
struct smemfs_inode *inode)
{
if (inode == NULL)
return;
smemfs_generate_path(path, inode->parent);
size_t length = strlen(inode->name);
memcpy((void*)*path, inode->name, length);
(*path)[length] = '\0';
*path = &(*path)[length];
}
static void smemfs_find(struct smemfs_inode *inode, char *buffer)
{
const char *ext;
if (inode == NULL)
return;
smemfs_find(inode->child, buffer);
ext = strrchr(inode->name, '.');
if (ext != NULL) {
if (strcmp(ext, ".elf") == 0) {
smemfs_generate_path((volatile char **)&buffer, inode);
/* TODO: check ELF validity */
terminal_write("(%x) %s\n", inode->type, inode->name);
}
}
smemfs_find(inode->sibling, buffer);
}
static void smemfs_walk(struct smemfs_inode *inode, int level, uint32_t bitmap)
{
const char *records;
if (inode == NULL)
return;
/* handle indentation */
for (int i = 0; i < level; ++i) {
records = "\t";
if ((bitmap & (1 << i)) != 0)
records = "|\t";
terminal_write(records);
}
/* handle file name and sibling dependencies */
records = "|-- (%x) %s";
bitmap |= 1 << level;
if (inode->sibling == NULL) {
records = "`-- (%x) %s";
bitmap &= ~(1 << level);
}
terminal_write(records, inode->type, inode->name);
/* handle file type */
if (inode->type == BFile_Type_Directory) {
terminal_write(":\n");
smemfs_walk(inode->child, level + 1, bitmap);
smemfs_walk(inode->sibling, level, bitmap);
return;
}
terminal_write("\n");
smemfs_walk(inode->sibling, level, bitmap);
}
int ls_main(int argc, char **argv)
{
if (smemfs_superblock.fake_root_inode != SMEMFS_FAKE_ROOT_INODE) {
terminal_write("smemfs not mounted !\n");
return (84);
}
if (argc > 1 && strcmp(argv[1], "-elf") == 0) {
char buffer[512];
smemfs_find(smemfs_superblock.root_inode, buffer);
return (0);
}
terminal_write("/:\n");
smemfs_walk(smemfs_superblock.root_inode, 0, 0x00000000);
return (0);
}