Call kos_fuse_lfn, add tools/mkdirrange, cleanup.

This commit is contained in:
Ivan Baravy 2018-05-10 00:08:52 +03:00
parent cdcb61a47f
commit d02cbfd7ef
9 changed files with 246 additions and 237 deletions

4
.gitignore vendored
View File

@ -3,5 +3,7 @@
*.o
kofu
kofuse
mkdirrange
*.img
*.xz
*.img.xz
*.img.info

3
README
View File

@ -11,6 +11,9 @@ Kofu
is Kolibri Filesystem in Userspace.
BUILD
KOLIBRI_TRUNK
Architecture

View File

@ -1,32 +0,0 @@
#ifndef KOS_H_INCLUDED
#define KOS_H_INCLUDED
#include <stdint.h>
#include <stdbool.h>
struct bdfe {
uint32_t attr;
uint32_t enc;
uint32_t ctime;
uint32_t cdate;
uint32_t atime;
uint32_t adate;
uint32_t mtime;
uint32_t mdate;
uint64_t size;
char name[264];
};
#define KF_READONLY 0x01
#define KF_HIDDEN 0x02
#define KF_SYSTEM 0x04
#define KF_LABEL 0x08
#define KF_FOLDER 0x10
uint32_t kos_time_to_epoch(uint32_t *time);
void *kos_fuse_init(int fd);
uint8_t *kos_fuse_readdir(const char *path, off_t offset);
void *kos_fuse_getattr(const char *path);
long *kos_fuse_read(const char *path, char *buf, size_t size, off_t offset);
#endif

53
kofu.c
View File

@ -8,10 +8,11 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "kocdecl.h"
#include "kolibri.h"
#define FGETS_BUF_LEN 4096
#define MAX_COMMAND_ARGS 42
#define DIRENTS_TO_READ 100
char cmd_buf[FGETS_BUF_LEN];
bool is_tty;
@ -37,31 +38,45 @@ char **split_args(char *s) {
}
void kofu_ls(char **arg) {
void *header = kos_fuse_readdir(arg[1], 0);
uint32_t file_cnt = ((uint32_t*)header)[1];
printf("file_cnt: %u\n", file_cnt);
struct bdfe *kf = header + 0x20;
for (; file_cnt > 0; file_cnt--) {
printf("%s\n", kf->name);
kf++;
struct f70s1ret *dir = (struct f70s1ret*)malloc(sizeof(struct f70s1ret) + sizeof(struct bdfe) * DIRENTS_TO_READ);
struct f70s1arg f70 = {1, 0, CP866, DIRENTS_TO_READ, dir, 0, arg[1]};
while (true) {
int status = kos_fuse_lfn(&f70);
printf("status = %d\n", status);
if (status != 0 && status != 6) {
abort();
}
f70.offset += dir->cnt;
for (size_t i = 0; i < dir->cnt; i++) {
printf("%s\n", dir->bdfes[i].name);
}
if (status == 6) {
break;
}
}
free(dir);
return;
}
void kofu_stat(char **arg) {
struct bdfe *kf = kos_fuse_getattr(arg[1]);
printf("attr: 0x%2.2x\n", kf->attr);
printf("size: %llu\n", kf->size);
struct bdfe file;
struct f70s5arg f70 = {5, 0, 0, 0, &file, 0, arg[1]};
kos_fuse_lfn(&f70);
printf("attr: 0x%2.2x\n", file.attr);
printf("size: %llu\n", file.size);
return;
}
void kofu_read(char **arg) {
size_t size;
size_t offset;
off_t offset;
sscanf(arg[2], "%zu", &size);
sscanf(arg[3], "%zu", &offset);
char *buf = (char*)malloc(size + 4096);
kos_fuse_read(arg[1], buf, size, offset);
sscanf(arg[3], "%llu", &offset);
uint8_t *buf = (uint8_t*)malloc(size);
struct f70s5arg f70 = {0, offset, offset >> 32, size, buf, 0, arg[1]};
kos_fuse_lfn(&f70);
for (size_t i = 0; i < size; i++) {
if (i % 32 == 0 && i != 0) {
printf("\n");
@ -69,6 +84,7 @@ void kofu_read(char **arg) {
printf("%2.2x", buf[i]);
}
printf("\n");
free(buf);
return;
}
@ -92,14 +108,13 @@ int main(int argc, char **argv) {
is_tty = isatty(STDIN_FILENO);
int fd = open(argv[1], O_RDONLY);
if (!kos_fuse_init(fd)) {
struct stat st;
fstat(fd, &st);
if (!kos_fuse_init(fd, st.st_size / 512)) {
exit(1);
}
//msg_few_args db 'usage: xfskos image [offset]',0x0a
//msg_file_not_found db 'file not found: '
//msg_unknown_command db 'unknown command',0x0a
//msg_not_xfs_partition db 'not xfs partition',0x0a
while(next_line()) {
if (!is_tty) {
prompt();

View File

@ -9,7 +9,9 @@
#include <stdlib.h>
#include <time.h>
#include <assert.h>
#include "kocdecl.h"
#include "kolibri.h"
#define DIRENTS_TO_READ 100
static void bdfe_to_stat(struct bdfe *kf, struct stat *st) {
if (kf->attr & KF_FOLDER) {
@ -20,9 +22,9 @@ static void bdfe_to_stat(struct bdfe *kf, struct stat *st) {
st->st_nlink = 1;
st->st_size = kf->size;
}
st->st_atim = (struct timespec){kos_time_to_epoch(&(kf->atime)), 0};
st->st_mtim = (struct timespec){kos_time_to_epoch(&(kf->mtime)), 0};
st->st_ctim = (struct timespec){kos_time_to_epoch(&(kf->ctime)), 0};
st->st_atim = (struct timespec){ .tv_sec = kos_time_to_epoch(&(kf->atime)) };
st->st_mtim = (struct timespec){ .tv_sec = kos_time_to_epoch(&(kf->mtime)) };
st->st_ctim = (struct timespec){ .tv_sec = kos_time_to_epoch(&(kf->ctime)) };
}
static void *kofuse_init(struct fuse_conn_info *conn,
@ -34,32 +36,34 @@ static void *kofuse_init(struct fuse_conn_info *conn,
static int kofuse_getattr(const char *path, struct stat *stbuf,
struct fuse_file_info *fi) {
(void) fi;
int res = 0;
(void) fi;
int res = 0;
struct bdfe *kf = kos_fuse_getattr(path);
bdfe_to_stat(kf, stbuf);
// res = -ENOENT;
return res;
struct bdfe file;
struct f70s5arg f70 = {5, 0, 0, 0, &file, 0, path};
kos_fuse_lfn(&f70);
bdfe_to_stat(&file, stbuf);
// res = -ENOENT;
return res;
}
static int kofuse_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi,
enum fuse_readdir_flags flags) {
(void) offset;
(void) fi;
(void) flags;
(void) offset;
(void) fi;
(void) flags;
void *header = kos_fuse_readdir(path, offset);
uint32_t i = *(uint32_t*)(header + 4);
struct bdfe *kf = header + 0x20;
for(; i>0; i--) {
filler(buf, kf->name, NULL, 0, 0);
kf++;
}
return 0;
struct f70s1ret *dir = (struct f70s1ret*)malloc(sizeof(struct f70s1ret) + sizeof(struct bdfe) * DIRENTS_TO_READ);
struct f70s1arg f70 = {1, 0, CP866, DIRENTS_TO_READ, dir, 0, path};
kos_fuse_lfn(&f70);
for (size_t i = 0; i < dir->cnt; i++) {
filler(buf, dir->bdfes[i].name, NULL, 0, 0);
}
free(dir);
return 0;
}
static int kofuse_open(const char *path, struct fuse_file_info *fi) {
@ -75,10 +79,11 @@ static int kofuse_open(const char *path, struct fuse_file_info *fi) {
static int kofuse_read(const char *path, char *buf, size_t size, off_t offset,
struct fuse_file_info *fi) {
(void) fi;
(void) fi;
kos_fuse_read(path, buf, size, offset);
return size;
struct f70s5arg f70 = {0, offset, offset >> 32, size, buf, 0, path};
kos_fuse_lfn(&f70);
return size;
}
static struct fuse_operations kofuse_oper = {
@ -95,6 +100,8 @@ int main(int argc, char *argv[]) {
exit(1);
}
int fd = open(argv[2], O_RDONLY);
kos_fuse_init(fd);
struct stat st;
fstat(fd, &st);
kos_fuse_init(fd, st.st_size / 512);
return fuse_main(argc-1, argv, &kofuse_oper, NULL);
}

View File

@ -14,21 +14,6 @@ include 'blkdev/disk_cache.inc'
include 'fs/fs_lfn.inc'
include 'crc.inc'
struct FS_FUNCTIONS
Free dd ?
Size dd ?
ReadFile dd ?
ReadFolder dd ?
CreateFile dd ?
WriteFile dd ?
SetFileEnd dd ?
GetFileInfo dd ?
SetFileInfo dd ?
Run dd ?
Delete dd ?
CreateFolder dd ?
ends
purge section,mov,add,sub
section '.text' executable align 16
@ -46,7 +31,7 @@ kos_time_to_epoch:
ret
;void *kos_fuse_init(int fd);
;void *kos_fuse_init(int fd, uint32_t sect_cnt);
public kos_fuse_init
kos_fuse_init:
push ebx esi edi ebp
@ -54,105 +39,29 @@ kos_fuse_init:
mov [pg_data.pages_free], (128*1024*1024)/0x1000
mov eax, [esp + 0x14]
mov [fd], eax
mov [file_disk.Size], 65536
mov [file_disk.fd], eax
mov eax, [esp + 0x18]
mov [file_disk.Sectors], eax
mov [file_disk.Logical], 512
stdcall disk_add, disk_functions, disk_name, file_disk, DISK_NO_INSERT_NOTIFICATION
mov [disk], eax
stdcall disk_media_changed, [disk], 1
mov eax, [disk]
cmp [eax + DISK.NumPartitions], 0
jnz .done
mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, msg_no_partition
mov edx, msg_no_partition.size
int 0x80
xor eax, eax
.done:
mov [fs_struct], eax
mov eax, [eax + DISK.NumPartitions]
pop ebp edi esi ebx
ret
;char *kos_fuse_readdir(const char *path, off_t offset)
public kos_fuse_readdir
kos_fuse_readdir:
;DEBUGF 1, '#kos_fuse_readdir\n'
push ebx esi edi ebp
mov edx, sf70_params
mov dword[edx + 0x00], 1
mov eax, [esp + 0x18] ; offset
mov [edx + 0x04], eax
mov dword[edx + 0x08], 1 ; cp866
mov dword[edx + 0x0c], 100
mov dword[edx + 0x10], sf70_buffer
mov eax, [esp + 0x14] ; path
mov byte[edx + 0x14], 0
mov [edx + 0x15], eax
mov ebx, sf70_params
public kos_fuse_lfn
kos_fuse_lfn:
push ebx
mov ebx, [esp + 8]
pushad ; file_system_lfn writes here
call file_system_lfn
popad
pop ebp edi esi ebx
mov eax, sf70_buffer
ret
;void *kos_fuse_getattr(const char *path)
public kos_fuse_getattr
kos_fuse_getattr:
;DEBUGF 1, '#kos_fuse_getattr\n'
push ebx esi edi ebp
mov edx, sf70_params
mov dword[edx + 0x00], 5
mov dword[edx + 0x04], 0
mov dword[edx + 0x08], 0
mov dword[edx + 0x0c], 0
mov dword[edx + 0x10], sf70_buffer
mov eax, [esp + 0x14] ; path
mov byte[edx + 0x14], 0
mov [edx + 0x15], eax
mov ebx, sf70_params
pushad ; file_system_lfn writes here
call file_system_lfn
popad
pop ebp edi esi ebx
mov eax, sf70_buffer
ret
;long *kos_fuse_read(const char *path, char *buf, size_t size, off_t offset)
public kos_fuse_read
kos_fuse_read:
push ebx esi edi ebp
mov edx, sf70_params
mov dword[edx + 0x00], 0
mov eax, [esp + 0x20] ; offset lo
mov dword[edx + 0x04], eax
mov dword[edx + 0x08], 0 ; offset hi
mov eax, [esp + 0x1c] ; size
mov dword[edx + 0x0c], eax
mov eax, [esp + 0x18] ; buf
mov dword[edx + 0x10], eax
mov eax, [esp + 0x14] ; path
mov byte[edx + 0x14], 0
mov [edx + 0x15], eax
mov ebx, sf70_params
pushad ; file_system_lfn writes here
call file_system_lfn
popad
pop ebp edi esi ebx
mov eax, 0
pop ebx
ret
@ -161,20 +70,22 @@ proc disk_read stdcall, userdata, buffer, startsector:qword, numsectors
mov eax, dword[startsector + 0] ; sector lo
mov edx, dword[startsector + 4] ; sector hi
imul ecx, eax, 512
mov eax, SYS_LSEEK
mov ebx, [fd]
mov eax, [userdata]
mov ebx, [eax + FILE_DISK.fd]
mov edx, SEEK_SET
mov eax, SYS_LSEEK
int 0x80
;DEBUGF 1, "lseek: %x\n", eax
popad
pushad
mov eax, SYS_READ
mov ebx, [fd]
mov eax, [userdata]
mov ebx, [eax + FILE_DISK.fd]
mov ecx, [buffer]
mov edx, [numsectors]
mov edx, [edx]
imul edx, 512
imul edx, [eax + FILE_DISK.Logical]
mov eax, SYS_READ
int 0x80
;DEBUGF 1, "read: %d\n", eax
popad
@ -185,22 +96,26 @@ endp
proc disk_write stdcall, userdata, buffer, startsector:qword, numsectors
ud2
pushad
mov eax, dword[startsector + 0] ; sector lo
mov edx, dword[startsector + 4] ; sector hi
imul ecx, eax, 512
add ecx, 2048*512
mov eax, SYS_LSEEK
mov ebx, [fd]
mov eax, [userdata]
mov ebx, [eax + FILE_DISK.fd]
mov edx, SEEK_SET
mov eax, SYS_LSEEK
int 0x80
;DEBUGF 1, "lseek: %x\n", eax
popad
pushad
mov eax, [userdata]
mov ebx, [eax + FILE_DISK.fd]
mov ecx, [buffer]
mov edx, [numsectors]
mov edx, [edx]
imul edx, [eax + FILE_DISK.Logical]
mov eax, SYS_WRITE
mov ecx, ebx
mov ebx, [fd]
mov edx, 512
int 0x80
;DEBUGF 1, "write: %d\n", eax
popad
@ -213,10 +128,11 @@ endp
; int querymedia(void* userdata, DISKMEDIAINFO* info);
proc disk_querymedia stdcall, hd_data, mediainfo
mov ecx, [mediainfo]
mov edx, [hd_data]
mov [ecx + DISKMEDIAINFO.Flags], 0
mov [ecx + DISKMEDIAINFO.SectorSize], 512
mov eax, [hd_data]
mov eax, dword[eax + FILE_DISK.Size + 0]
mov eax, [edx + FILE_DISK.Logical]
mov [ecx + DISKMEDIAINFO.SectorSize], eax
mov eax, [edx + FILE_DISK.Sectors]
mov dword [ecx + DISKMEDIAINFO.Capacity], eax
mov dword [ecx + DISKMEDIAINFO.Capacity + 4], 0
@ -252,21 +168,15 @@ proc alloc_pages _cnt
endp
free:
ret
proc kernel_free blah
ret
endp
mutex_init:
mutex_lock:
mutex_unlock:
ret
put_board:
pushad
mov eax, SYS_WRITE
@ -325,16 +235,12 @@ prevent_medium_removal:
Read_TOC:
commit_pages:
release_pages:
fs_execute:
mutex_init:
mutex_lock:
mutex_unlock:
ret
proc fs_execute
; edx = flags
; ecx -> cmdline
; ebx -> absolute file path
; eax = string length
ret
endp
section '.data' writeable align 16
include_debug_strings
@ -350,16 +256,15 @@ disk_functions:
disk_functions_end:
struct FILE_DISK
Size dd ?
fd dd ?
Sectors dd ?
Logical dd ? ; sector size
ends
file_disk FILE_DISK
alloc_pos dd alloc_base
sf70_params rd 6
msg_no_partition db 'no partition detected',0x0a
msg_no_partition.size = $ - msg_no_partition
disk_name db 'hd0',0
IncludeIGlobals
; crap
current_slot dd ?
pg_data PG_DATA
ide_channel1_mutex MUTEX
@ -370,16 +275,14 @@ ide_channel5_mutex MUTEX
ide_channel6_mutex MUTEX
ide_channel7_mutex MUTEX
ide_channel8_mutex MUTEX
IncludeIGlobals
section '.bss' writeable align 16
fd rd 1
file_disk FILE_DISK
disk dd ?
alloc_base rb 32*1024*1024
fs_struct rd 1
sf70_buffer rb 16*1024*1024
alloc_base rb 8*1024*1024
IncludeUGlobals
; crap
DiskNumber db ?
ChannelNumber db ?
DevErrorCode dd ?
@ -387,4 +290,4 @@ CDSectorAddress dd ?
CDDataBuf_pointer dd ?
DRIVE_DATA: rb 0x4000
cdpos dd ?
cd_appl_data rd 1
cd_appl_data dd ?

74
kolibri.h Normal file
View File

@ -0,0 +1,74 @@
#ifndef KOLIBRI_H_INCLUDED
#define KOLIBRI_H_INCLUDED
#include <stdint.h>
enum encoding {
DEFAULT,
CP866,
UTF16,
UTF8,
};
struct bdfe {
uint32_t attr;
uint32_t enc;
uint32_t ctime;
uint32_t cdate;
uint32_t atime;
uint32_t adate;
uint32_t mtime;
uint32_t mdate;
uint64_t size;
char name[264];
};
struct f70s0arg {
uint32_t sf;
uint32_t offset_lo;
uint32_t offset_hi;
uint32_t size;
void *buf;
uint8_t zero;
const char *path;
} __attribute__((packed));
struct f70s1arg {
uint32_t sf;
uint32_t offset;
uint32_t encoding;
uint32_t size;
void *buf;
uint8_t zero;
const char *path;
} __attribute__((packed));
struct f70s1ret {
uint32_t version;
uint32_t cnt;
uint32_t total_cnt;
uint32_t reserved[5];
struct bdfe bdfes[0];
};
struct f70s5arg {
uint32_t sf;
uint32_t reserved1;
uint32_t flags;
uint32_t reserved2;
void *buf;
uint8_t zero;
const char *path;
} __attribute__((packed));
#define KF_READONLY 0x01
#define KF_HIDDEN 0x02
#define KF_SYSTEM 0x04
#define KF_LABEL 0x08
#define KF_FOLDER 0x10
uint32_t kos_time_to_epoch(uint32_t *time);
void *kos_fuse_init(int fd, uint32_t sect_cnt);
int kos_fuse_lfn(void *f70arg);
#endif

View File

@ -1,27 +1,32 @@
FASM=fasm
CC=gcc
CFLAGS=-m32 -Wall -Wextra -g -O0 -D_FILE_OFFSET_BITS=64
LDFLAGS=-m32
CFLAGS=-Wall -Wextra -g -O0
CFLAGS_32=-m32 -D_FILE_OFFSET_BITS=64
LDFLAGS=
LDFLAGS_32=-m32
all: kofu kofuse
all: kofu kofuse tools/mkdirrange
kofu: kofu.o kocdecl.o
$(CC) $(LDFLAGS) $^ -o $@
kofu: kofu.o kolibri.o
$(CC) $(LDFLAGS) $(LDFLAGS_32) $^ -o $@
kofuse: kofuse.o kocdecl.o
$(CC) $(LDFLAGS) $^ -o $@ `pkg-config fuse3 --libs`
kofuse: kofuse.o kolibri.o
$(CC) $(LDFLAGS) $(LDFLAGS_32) $^ -o $@ `pkg-config fuse3 --libs`
kocdecl.o: kocdecl.asm kocdecl.h $(KERNEL_TRUNK)/fs/ext.inc $(KERNEL_TRUNK)/fs/xfs.inc $(KERNEL_TRUNK)/fs/xfs.asm
INCLUDE="$(KERNEL_TRUNK);$(KERNEL_TRUNK)/fs;$(KERNEL_TRUNK)/blkdev" $(FASM) $< $@ -m 1234567
kolibri.o: kolibri.asm kolibri.h
INCLUDE="$(KOLIBRI_TRUNK)" $(FASM) $< $@ -m 100000
kofu.o: kofu.c kocdecl.h
$(CC) $(CFLAGS) -c $<
kofu.o: kofu.c kolibri.h
$(CC) $(CFLAGS) $(CFLAGS_32) -c $<
kofuse.o: kofuse.c kocdecl.h
$(CC) $(CFLAGS) `pkg-config fuse3 --cflags` -c $<
kofuse.o: kofuse.c kolibri.h
$(CC) $(CFLAGS) $(CFLAGS_32) `pkg-config fuse3 --cflags` -c $<
tools/mkdirrange: tools/mkdirrange.c
$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@
.PHONY: all clean
clean:
rm -f *.o kofu kofuse
rm -f *.o kofu kofuse tools/mkdirrange

32
tools/mkdirrange.c Normal file
View File

@ -0,0 +1,32 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <string.h>
int main(int argc, char *argv[])
{
unsigned long begin, end, current;
char dirname[256] = "dir0123456789_blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah\0";
if(argc != 3) {
fprintf(stderr, "%s num_begin num_end\n", argv[0]);
exit(1);
}
sscanf(argv[1], "%lu", &begin);
sscanf(argv[2], "%lu", &end);
for(current=begin; current<=end; current++) {
sprintf(dirname + 3, "%10.10lu", current);
dirname[13] = '_';
if(mkdir(dirname, 0755)) {
fprintf(stderr, "error: %s\n", strerror(errno));
exit(1);
}
}
return 0;
}