Added a file slurp utility to read files

This commit is contained in:
Hopeless Tyromancy 2026-03-05 13:11:33 -05:00
parent 3868eb4ac5
commit 993092a854
12 changed files with 100 additions and 37 deletions

BIN
bin/os

Binary file not shown.

BIN
image.hdd

Binary file not shown.

2
limine

@ -1 +1 @@
Subproject commit eecf8d682a749701691e31b89f66f330f525c611
Subproject commit e0e61c946933696453f591da525ab1f8a66a553d

Binary file not shown.

View File

@ -1,11 +1,12 @@
obj/src/main.c.o: src/main.c src/../include/limine.h src/prompt/lex.h \
src/prompt/file.h src/prompt/file.h src/acpi.h src/common.h src/ahci.h \
src/alloc.h src/apic.h src/fat32.h src/lib/ctype.h src/lib/string.h \
src/lib/stdio.h src/lib/malloc.h src/lib/../kbd.h src/lib/../print.h
src/prompt/file.h src/acpi.h src/common.h src/ahci.h src/alloc.h \
src/apic.h src/fat32.h src/lib/ctype.h src/lib/string.h \
src/lib/../lib/stdio.h src/lib/../lib/malloc.h \
src/lib/../lib/../common.h src/lib/../lib/../kbd.h \
src/lib/../lib/../print.h src/lib/stdio.h src/print.h
src/../include/limine.h:
src/prompt/lex.h:
src/prompt/file.h:
src/prompt/file.h:
src/acpi.h:
src/common.h:
src/ahci.h:
@ -14,7 +15,10 @@ src/apic.h:
src/fat32.h:
src/lib/ctype.h:
src/lib/string.h:
src/lib/../lib/stdio.h:
src/lib/../lib/malloc.h:
src/lib/../lib/../common.h:
src/lib/../lib/../kbd.h:
src/lib/../lib/../print.h:
src/lib/stdio.h:
src/lib/malloc.h:
src/lib/../kbd.h:
src/lib/../print.h:
src/print.h:

Binary file not shown.

View File

@ -190,8 +190,9 @@ static fat32_dirent_t* fat32_find(int port, fat32_vol_t* vol, u32 dir_cluster, c
if ((e->attr & ATTR_LFN) == ATTR_LFN) continue;
if (e->attr & ATTR_VOL_ID) continue;
if (memcmp(e->name, name83, 8) == 0 && memcmp(e->ext, name83 + 8, 3) == 0) {
if (strneq(e->name, name83, 8) && strneq(e->ext, name83 + 8, 3)) {
fat32_dirent_t* result = (fat32_dirent_t*) alloc(sizeof(fat32_dirent_t));
printf("\nFOUND: %.8s'.'%3s\n", e->name, e->ext);
*result = *e;
return result;
}
@ -205,9 +206,15 @@ not_found:
}
typedef struct FILE {
int port;
fat32_vol_t* vol;
fat32_dirent_t info;
} FILE;
// fat32_find_path: resolve a full path like "/dir/subdir/file.txt"
// leading slash is optional, "" or "/" both refer to root
static fat32_dirent_t* fat32_find_path(int port, fat32_vol_t* vol, const char* path) {
static FILE* fat32_find_path(int port, fat32_vol_t* vol, const char* path) {
u32 cluster = vol->root_cluster;
// skip leading slash
@ -233,6 +240,9 @@ static fat32_dirent_t* fat32_find_path(int port, fat32_vol_t* vol, const char* p
// convert component to 8.3
u8 name83[11];
fat32_to_name83(part, name83);
printf("\nNAME83: %.8s.%.3s\n", name83, name83+8);
fat32_dirent_t* e = fat32_find(port, vol, cluster, name83);
if (!e) return NULL;
@ -245,8 +255,54 @@ static fat32_dirent_t* fat32_find_path(int port, fat32_vol_t* vol, const char* p
}
// last component — return it whether file or dir
return e;
struct FILE* ret = (struct FILE*) alloc(sizeof(struct FILE));
if(!ret) {
printf("fat32_find_path: couldn't allocate FILE structure\n");
return ret;
}
ret->port = port;
ret->vol = vol;
ret->info = *e;
return ret;
}
return NULL;
}
static u32 fat32_cluster(fat32_dirent_t* dirent) {
return (((u32)dirent->cluster_high) << 16) | (u32)(dirent->cluster_low);
}
static u8* slurp(struct FILE* file) {
if(!file) {
printf("fat32_slurp: File pointer is NULL\n");
return NULL;
}
if(file->info.attr & ATTR_DIR) {
printf("fat32_slurp: %.8s'.'%.3s: Is a directory\n", file->info.name, file->info.ext);
return NULL;
}
if(!file->info.file_size) {
printf("fat32_slurp: %.8s'.'%.3s: Refusing to slurp empty file\n", file->info.name, file->info.ext);
return NULL;
}
size_t sz = (file->info.file_size / TODO_MAKE_ME_DYNAMIC_BLOCK_SIZE) + 1;
sz *= TODO_MAKE_ME_DYNAMIC_BLOCK_SIZE;
u8* buff = (u8*) calloc(file->info.file_size, 1);
if(!buff) {
printf("fat32_slurp: %.8s'.'%.3s: Failed to allocate buffer of size %u\n", file->info.name, file->info.ext, file->info.file_size);
}
u8* write_ptr = &buff[0];
for(u32 cluster = fat32_cluster(&file->info); !fat32_is_eof(cluster); cluster = fat32_next(file->port, file->vol, cluster)) {
fat32_read_cluster(file->port, file->vol, cluster, write_ptr);
write_ptr += TODO_MAKE_ME_DYNAMIC_BLOCK_SIZE * (file->vol->sectors_per_cluster);
}
return buff;
}

View File

@ -1,8 +1,26 @@
#pragma once
#include "../lib/stdio.h"
static size_t strlen(const char* str) {
size_t len = 0;
while(*(str++))
len++;
return len;
}
static bool strneq(const char* l, const char* r, size_t n) {
for(size_t i = 0; i < n; i++) {
if(r[i] != l[i]) {
return false;
}
}
return true;
}
static char* index(char* str, int ch) {
for(;*str && *str != ch; str++)
;
return *str?str : NULL;
}

View File

@ -186,6 +186,7 @@ void ls(int port, int indent, fat32_vol_t* vol, u32 cluster) {
put(dir[i].ext[c]);
}
}
printf(" %d", dir[i].file_size);
put('\n');
if(dir[i].attr & ATTR_DIR) {
@ -329,11 +330,16 @@ void kmain() {
ls(port, 0, &vol, vol.root_cluster);
print("Attempting to find FORTU.NE\n");
fat32_dirent_t* fortune = fat32_find_path(port, &vol, "fort/fortu.ne");
struct FILE* fortune = fat32_find_path(port, &vol, "fort/fortu.ne");
printf("Fortune size: %d\n", fortune->file_size);
printf("Fortune size: %d\n", fortune->info.file_size);
u8* fort = slurp(fortune);
printn(fort, fortune->info.file_size);
free(fort);
hang();
}

View File

@ -1,6 +1,7 @@
#include "../common.h"
#include "../print.h"
#include "../lib/string.h"
#include "iden.h"
@ -9,14 +10,7 @@ struct iden identbl[MAX_IDEN];
static size_t identbl_len = 0;
static bool strneq(const char* l, const char* r, size_t n) {
for(size_t i = 0; i < n; i++) {
if(r[i] != l[i])
return false;
}
return true;
}
size_t register_iden(const char* data, size_t len, uint64_t hash) {
size_t i;

View File

@ -11,21 +11,6 @@ static int lex_error(struct file* state, const char* err) {
return 1;
}
static bool strneq(const char* l, const char* r, size_t n) {
for(size_t i = 0; i < n; i++) {
if(r[i] != l[i])
return false;
}
return true;
}
static char* index(char* str, int ch) {
for(;*str && *str != ch; str++)
;
return *str?str : NULL;
}
#define MAX_TOK (1024*1024)
struct token token_pool[MAX_TOK];