From 4f97503f45a59678ce1f607c1ba07b321f4f6299 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Thu, 20 Apr 2023 19:24:29 +0700 Subject: [PATCH 001/101] feat: initial shell configuration --- .vscode/launch.json | 6 +++++- makefile | 3 +++ src/idt.c | 6 +++++- src/interrupt.c | 48 +++++++++++++++++++++++++++++++-------------- src/user-shell.c | 35 ++++++++++++++++++++++++++++++--- 5 files changed, 78 insertions(+), 20 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 4b3f1ea..b6b1793 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -31,11 +31,15 @@ "text": "symbol-file kernel", "description": "Get kernel symbols" }, + { + "text": "add-symbol-file shell_elf", + "description": "Get shell symbols" + }, { "text": "set output-radix 16", "description": "Use hexadecimal output" } - ], + ], "avoidWindowsConsoleRedirection": true }, { diff --git a/makefile b/makefile index 25d1f31..822cf11 100644 --- a/makefile +++ b/makefile @@ -82,6 +82,9 @@ user-shell: @$(LIN) -T $(SOURCE_FOLDER)/user-linker.ld -melf_i386 \ user-entry.o user-shell.o -o $(OUTPUT_FOLDER)/shell @echo Linking object shell object files and generate flat binary... + @$(LIN) -T $(SOURCE_FOLDER)/user-linker.ld -melf_i386 --oformat=elf32-i386\ + user-entry.o user-shell.o -o $(OUTPUT_FOLDER)/shell_elf + @echo Linking object shell object files and generate ELF32 for debugging... @size --target=binary bin/shell @rm -f *.o diff --git a/src/idt.c b/src/idt.c index a102120..fecc555 100644 --- a/src/idt.c +++ b/src/idt.c @@ -36,7 +36,11 @@ void initialize_idt(void) { for (int i = 0; i < ISR_STUB_TABLE_LIMIT; i++) { - set_interrupt_gate(i, isr_stub_table[i], GDT_KERNEL_CODE_SEGMENT_SELECTOR, 0); + uint8_t privilege = 0; + + if (i >= 0x30 && i <= 0x3F) privilege = 0x3; + + set_interrupt_gate(i, isr_stub_table[i], GDT_KERNEL_CODE_SEGMENT_SELECTOR, privilege); } __asm__ volatile("lidt %0" : : "m"(_idt_idtr)); diff --git a/src/interrupt.c b/src/interrupt.c index 44c00a2..e2ec66a 100644 --- a/src/interrupt.c +++ b/src/interrupt.c @@ -3,6 +3,9 @@ #include "lib-header/portio.h" #include "lib-header/framebuffer.h" #include "lib-header/keyboard.h" +#include "lib-header/idt.h" +#include "lib-header/fat32.h" +#include "lib-header/stdmem.h" void io_wait(void) { out(0x80, 0); @@ -45,20 +48,6 @@ void pic_remap(void) { out(PIC2_DATA, a2); } -void main_interrupt_handler( - __attribute__((unused)) struct CPURegister cpu, - uint32_t int_number, - __attribute__((unused)) struct InterruptStack info -) { - switch (int_number) { - case 0xE: - break; - case 0x21: - keyboard_isr(); - break; - } -} - void activate_keyboard_interrupt(void) { out(PIC1_DATA, PIC_DISABLE_ALL_MASK ^ (1 << IRQ_KEYBOARD)); out(PIC2_DATA, PIC_DISABLE_ALL_MASK); @@ -72,4 +61,33 @@ void set_tss_kernel_current_stack(void) { _interrupt_tss_entry.esp0 = stack_ptr + 8; } -struct TSSEntry _interrupt_tss_entry; \ No newline at end of file +struct TSSEntry _interrupt_tss_entry = { + .ss0 = GDT_KERNEL_DATA_SEGMENT_SELECTOR, +}; + +void main_interrupt_handler(struct CPURegister cpu, uint32_t int_number, struct InterruptStack info) { + switch (int_number) { + case PIC1_OFFSET + IRQ_KEYBOARD: + keyboard_isr(); + break; + case 0x30: + syscall(cpu, info); + break; + } +} + +void syscall(struct CPURegister cpu, __attribute__((unused)) struct InterruptStack info) { + if (cpu.eax == 0) { + struct FAT32DriverRequest request = *(struct FAT32DriverRequest*) cpu.ebx; + *((int8_t*) cpu.ecx) = read(request); + } else if (cpu.eax == 4) { + keyboard_state_activate(); + __asm__("sti"); // Due IRQ is disabled when main_interrupt_handler() called + while (is_keyboard_blocking()); + char buf[KEYBOARD_BUFFER_SIZE]; + get_keyboard_buffer(buf); + memcpy((char *) cpu.ebx, buf, cpu.ecx); + } else if (cpu.eax == 5) { + puts((char *) cpu.ebx, cpu.ecx, cpu.edx); // Modified puts() on kernel side + } +} diff --git a/src/user-shell.c b/src/user-shell.c index fa141a8..52d8d13 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -1,7 +1,36 @@ #include "lib-header/stdtype.h" +#include "lib-header/fat32.h" + +void syscall(uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx) { + __asm__ volatile("mov %0, %%ebx" : /* */ : "r"(ebx)); + __asm__ volatile("mov %0, %%ecx" : /* */ : "r"(ecx)); + __asm__ volatile("mov %0, %%edx" : /* */ : "r"(edx)); + __asm__ volatile("mov %0, %%eax" : /* */ : "r"(eax)); + // Note : gcc usually use %eax as intermediate register, + // so it need to be the last one to mov + __asm__ volatile("int $0x30"); +} int main(void) { - __asm__ volatile("mov %0, %%eax" : /* */ : "r"(0xDEADBEEF)); - while (TRUE); + struct ClusterBuffer cl = {0}; + struct FAT32DriverRequest request = { + .buf = &cl, + .name = "ikanaide", + .ext = "\0\0\0", + .parent_cluster_number = ROOT_CLUSTER_NUMBER, + .buffer_size = CLUSTER_SIZE, + }; + int32_t retcode; + syscall(0, (uint32_t) &request, (uint32_t) &retcode, 0); + if (retcode == 0) + syscall(5, (uint32_t) "owo\n", 4, 0xF); + + char buf[16]; + while (TRUE) { + syscall(4, (uint32_t) buf, 16, 0); + syscall(5, (uint32_t) buf, 16, 0xF); + } + return 0; -} \ No newline at end of file +} + From 0db28f869299141cd4cb7076f7f54375e8668626 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Fri, 21 Apr 2023 19:32:51 +0700 Subject: [PATCH 002/101] feat: basic command parser --- src/external-inserter.c | 5 +- src/fat32.c | 56 +++++++++++- src/interrupt.c | 12 ++- src/lib-header/fat32.h | 1 + src/user-shell.c | 195 +++++++++++++++++++++++++++++++++++++--- 5 files changed, 254 insertions(+), 15 deletions(-) diff --git a/src/external-inserter.c b/src/external-inserter.c index 7127031..76e440a 100644 --- a/src/external-inserter.c +++ b/src/external-inserter.c @@ -1,9 +1,10 @@ #include #include +#include "lib-header/stdtype.h" // Usual gcc fixed width integer type -typedef u_int32_t uint32_t; -typedef u_int8_t uint8_t; +// typedef u_int32_t uint32_t; +// typedef u_int8_t uint8_t; // Manual import from fat32.h, disk.h, & stdmem.h due some issue with size_t #define BLOCK_SIZE 512 diff --git a/src/fat32.c b/src/fat32.c index f9efdb7..25f4296 100644 --- a/src/fat32.c +++ b/src/fat32.c @@ -111,7 +111,7 @@ void create_fat32(void) { // Initialize root directory struct FAT32DirectoryTable root; - init_directory_table(&root, "root", 2); + init_directory_table(&root, "root\0\0\0", 2); write_clusters(&root, 2, 1); } @@ -885,3 +885,57 @@ void set_access_datetime(struct FAT32DirectoryEntry *entry) { entry->access_date = ((FTTimestamp & 0xFFFF0000) >> 16); entry->access_time = (FTTimestamp & 0x0000FFFF); } + +// uint32_t read_cluster_number(char** directories, int count, uint16_t latest_parent_cluster_number) { + +// // return ROOT_CLUSTER_NUMBER if not found + +// read_clusters(&driver_state.dir_table_buf, latest_parent_cluster_number, 1); + +// int i = 0; +// struct FAT32DirectoryEntry *entry; +// uint16_t current_cluster_number = latest_parent_cluster_number; + +// // Find every directory table until the last one is found +// while (i < count) +// { +// bool found_matching_directory = FALSE; +// bool end_of_directory = FALSE; +// uint16_t temp_cluster_number = current_cluster_number; + +// while (!end_of_directory && !found_matching_directory) { + +// // Traverse the table in examined cluster. Starts from 1 because the first +// // entry of the table is the directory itself +// for (uint8_t i = 1; i < CLUSTER_SIZE / sizeof(struct FAT32DirectoryEntry) && !found_matching_directory; i++) { +// entry = &(driver_state.dir_table_buf.table[i]); +// found_matching_directory = !is_entry_empty(entry) && (memcmp(entry->name, directories[i], 8) == 0) && is_subdirectory(entry); +// } + +// // If the cluster_number is EOF, then we've finished examining the last +// // cluster of the directory +// end_of_directory = (driver_state.fat_table.cluster_map[temp_cluster_number] & +// 0x0000FFFF) == 0xFFFF; + +// // If directory is found, get out of the loop +// if (found_matching_directory) +// continue; + +// // Move onto the next cluster if it's not the end yet +// if (!end_of_directory) { +// temp_cluster_number = driver_state.fat_table.cluster_map[temp_cluster_number]; +// read_clusters(&driver_state.dir_table_buf, (uint32_t)temp_cluster_number, 1); +// } +// } + +// if (!found_matching_directory) { +// return ROOT_CLUSTER_NUMBER; +// } + +// i++; +// current_cluster_number = entry->cluster_low; +// } + +// return current_cluster_number; + +// } diff --git a/src/interrupt.c b/src/interrupt.c index e2ec66a..c4369be 100644 --- a/src/interrupt.c +++ b/src/interrupt.c @@ -80,14 +80,22 @@ void syscall(struct CPURegister cpu, __attribute__((unused)) struct InterruptSta if (cpu.eax == 0) { struct FAT32DriverRequest request = *(struct FAT32DriverRequest*) cpu.ebx; *((int8_t*) cpu.ecx) = read(request); - } else if (cpu.eax == 4) { + } + + else if (cpu.eax == 4) { keyboard_state_activate(); __asm__("sti"); // Due IRQ is disabled when main_interrupt_handler() called while (is_keyboard_blocking()); char buf[KEYBOARD_BUFFER_SIZE]; get_keyboard_buffer(buf); memcpy((char *) cpu.ebx, buf, cpu.ecx); - } else if (cpu.eax == 5) { + } + + else if (cpu.eax == 5) { puts((char *) cpu.ebx, cpu.ecx, cpu.edx); // Modified puts() on kernel side + } + + else if (cpu.eax == 6) { + } } diff --git a/src/lib-header/fat32.h b/src/lib-header/fat32.h index a7f46c8..3019cde 100644 --- a/src/lib-header/fat32.h +++ b/src/lib-header/fat32.h @@ -249,6 +249,7 @@ int8_t read_directory(struct FAT32DriverRequest request); * @return Error code: 0 success - 1 not a file - 2 not enough buffer - 3 not * found - -1 unknown - 4 invalid parent cluster */ + int8_t read(struct FAT32DriverRequest request); /** diff --git a/src/user-shell.c b/src/user-shell.c index 52d8d13..7e9be3d 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -1,5 +1,34 @@ #include "lib-header/stdtype.h" #include "lib-header/fat32.h" +#include "lib-header/stdmem.h" + +#define SHELL_BUFFER_SIZE 256 +#define COMMAND_MAX_SIZE 32 +#define COMMAND_COUNT 12 +#define DIRECTORY_NAME_LENGTH 8 +#define INDEXES_MAX_COUNT SHELL_BUFFER_SIZE+1 +const char command_list[COMMAND_COUNT][COMMAND_MAX_SIZE] = { + "cd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + "ls\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + "mkdir\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + "cat\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + "cp\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + "rm\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + "mv\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + "whereis\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", +}; + +struct CurrentDirectoryInfo +{ + uint16_t parent_cluster_number; + uint16_t current_cluster_number; + char current_directory_name[8]; + +} __attribute__((packed)); void syscall(uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx) { __asm__ volatile("mov %0, %%ebx" : /* */ : "r"(ebx)); @@ -11,24 +40,170 @@ void syscall(uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx) { __asm__ volatile("int $0x30"); } -int main(void) { - struct ClusterBuffer cl = {0}; +void get_buffer_indexes(char* buf, int* indexes, char delimiter, int starting_index, int buffer_length) { + + int i = starting_index; + int limit = i + buffer_length; + int count = 0; + bool stop = FALSE; + while (i < limit && !stop) + { + while(i < limit && buf[i] == delimiter) i++; + + if (i < limit) + { + indexes[count] = i; + count++; + + if (buf[i] == '\0') + { + stop = TRUE; + } + } + + while(i < limit && buf[i] != delimiter) i++; + } + + indexes[count] = limit; +} + +int get_command_index(char* buf, int starting_index, int command_length) { + // return -1 if command not found + // return command_list index if found + + if (command_length > COMMAND_MAX_SIZE) return -1; + + for (int i = 0; i < COMMAND_COUNT; i++) + { + if (memcmp(buf + starting_index, command_list[i], command_length) == 0) return i; + } + + return -1; +} + +void reset_indexes(int* indexes) +{ + for (int i = 0; i < INDEXES_MAX_COUNT; i++) indexes[i] = -1; +} + +int get_words_count(int* indexes) +{ + int i = 0; + while (i < INDEXES_MAX_COUNT && indexes[i] != -1) i++; + return i-1; +} + +bool is_back_path(int* buf, int starting_index, int length) +{ + for (int i = starting_index; i < starting_index+length; i++) + { + if (buf[i] != '.') return FALSE; + } + + return TRUE; +} + + +void cd_command(char* buf, int* indexes, struct CurrentDirectoryInfo* info) +{ + if (get_words_count(indexes) != 2) + { + // tulis parameter cd tidak valid + return; + } + int index = indexes[1]; + int length = indexes[2] - indexes[1]; + + int param_indexes[INDEXES_MAX_COUNT]; + reset_indexes(param_indexes); + + get_buffer_indexes(buf, param_indexes, '/', index, length); + + int i = 0; + + while(i < INDEXES_MAX_COUNT-1 && param_indexes[i+1] != -1) + { + int param_index = param_indexes[i]; + int param_length = param_indexes[i+1] - param_indexes[i]; + i++; + + if (param_length == 1 && buf[param_index] == '.') + { + continue; + } + + else if (is_back_path(buf, param_index, param_length)) + { + // TODO :go to parent dir + } + + else + { + // TODO :go to target dir + } + } +} + +void ls_command(uint16_t current_cluster_number, struct CurrentDirectoryInfo info) +{ + struct ClusterBuffer cl[5]; struct FAT32DriverRequest request = { .buf = &cl, - .name = "ikanaide", + .name = info.current_directory_name, .ext = "\0\0\0", - .parent_cluster_number = ROOT_CLUSTER_NUMBER, - .buffer_size = CLUSTER_SIZE, + .parent_cluster_number = info.current_cluster_number, + .buffer_size = CLUSTER_SIZE * 5, }; + int32_t retcode; + syscall(0, (uint32_t) &request, (uint32_t) &retcode, 0); - if (retcode == 0) - syscall(5, (uint32_t) "owo\n", 4, 0xF); - char buf[16]; + if (retcode == 0) { + struct FAT32DirectoryTable dirTable[5] = request.buf; + + int i = 0; + int entry_count = 0; + int dir_table_count = dirTable->table->filesize / CLUSTER_SIZE; + + while (i < dir_table_count) + { + int j = 1; + while(j < dirTable[i].table->n_of_entries) + { + //TODO : catat nama file/dir + + j++; + } + + i++; + } + } +} + +int main(void) { + + char buf[SHELL_BUFFER_SIZE]; + int word_indexes[INDEXES_MAX_COUNT]; + // char paths[PATH_MAX_COUNT][8]; + // int current_path_count = 0; + // uint16_t parent_cluster_number = ROOT_CLUSTER_NUMBER; + + struct CurrentDirectoryInfo current_directory_info = + { + .parent_cluster_number = ROOT_CLUSTER_NUMBER, + .current_cluster_number = ROOT_CLUSTER_NUMBER, + .current_directory_name = "root\0\0\0", + }; + + // fungsi atas-atas belum fix :D + while (TRUE) { - syscall(4, (uint32_t) buf, 16, 0); - syscall(5, (uint32_t) buf, 16, 0xF); + + reset_indexes(word_indexes); + + syscall(4, (uint32_t) buf, SHELL_BUFFER_SIZE, 0); + syscall(5, (uint32_t) buf, SHELL_BUFFER_SIZE, 0xF); // syscall ini belum implement fungsi put } return 0; From 4cb6ad8c5d74a64938e4f6ee498e13a29fb73a19 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Fri, 21 Apr 2023 21:46:08 +0700 Subject: [PATCH 003/101] fix: index structure --- src/user-shell.c | 90 ++++++++++++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 38 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index 7e9be3d..6abaf26 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -6,7 +6,7 @@ #define COMMAND_MAX_SIZE 32 #define COMMAND_COUNT 12 #define DIRECTORY_NAME_LENGTH 8 -#define INDEXES_MAX_COUNT SHELL_BUFFER_SIZE+1 +#define INDEXES_MAX_COUNT SHELL_BUFFER_SIZE const char command_list[COMMAND_COUNT][COMMAND_MAX_SIZE] = { "cd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "ls\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", @@ -30,6 +30,16 @@ struct CurrentDirectoryInfo } __attribute__((packed)); +struct IndexInfo { + int index; + int length; +} __attribute__((packed)); + +struct IndexInfo defaultIndexInfo = { + .index = -1, + .length = 0, +}; + void syscall(uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx) { __asm__ volatile("mov %0, %%ebx" : /* */ : "r"(ebx)); __asm__ volatile("mov %0, %%ecx" : /* */ : "r"(ecx)); @@ -40,36 +50,36 @@ void syscall(uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx) { __asm__ volatile("int $0x30"); } -void get_buffer_indexes(char* buf, int* indexes, char delimiter, int starting_index, int buffer_length) { +void get_buffer_indexes(char* buf, struct IndexInfo* indexes, char delimiter, int starting_index, int buffer_length) { + + // contoh penggunaan: + // buf = " 12 45 79 \0" int i = starting_index; int limit = i + buffer_length; int count = 0; - bool stop = FALSE; - while (i < limit && !stop) + + reset_indexes(indexes); + + while (i < limit && buf[i] != '\0') { - while(i < limit && buf[i] == delimiter) i++; + while(i < limit && buf[i] == delimiter && buf[i] != '\0') i++; - if (i < limit) - { - indexes[count] = i; - count++; + if (i >= limit || buf[i] == '\0') break; - if (buf[i] == '\0') - { - stop = TRUE; - } - } + indexes[count].index = i; - while(i < limit && buf[i] != delimiter) i++; - } + while(i < limit && buf[i] != delimiter && buf[i] != '\0') i++; + + indexes[count].length = (i - indexes[count].index); - indexes[count] = limit; + count++; + } } -int get_command_index(char* buf, int starting_index, int command_length) { +int get_command_number(char* buf, int starting_index, int command_length) { // return -1 if command not found - // return command_list index if found + // return command_list number if found if (command_length > COMMAND_MAX_SIZE) return -1; @@ -81,16 +91,24 @@ int get_command_index(char* buf, int starting_index, int command_length) { return -1; } -void reset_indexes(int* indexes) +void reset_indexes(struct IndexInfo* indexes) { - for (int i = 0; i < INDEXES_MAX_COUNT; i++) indexes[i] = -1; + for (int i = 0; i < INDEXES_MAX_COUNT; i++) { + indexes[i] = defaultIndexInfo; + } } -int get_words_count(int* indexes) +bool is_default_index(struct IndexInfo index_info) { - int i = 0; - while (i < INDEXES_MAX_COUNT && indexes[i] != -1) i++; - return i-1; + return index_info.index == -1 && index_info.length == 0; +} + +int get_words_count(struct IndexInfo* indexes) +{ + int count = 0; + while (count < INDEXES_MAX_COUNT && !is_default_index(indexes[count])) count++; + + return count; } bool is_back_path(int* buf, int starting_index, int length) @@ -103,36 +121,30 @@ bool is_back_path(int* buf, int starting_index, int length) return TRUE; } - -void cd_command(char* buf, int* indexes, struct CurrentDirectoryInfo* info) +void cd_command(char* buf, struct IndexInfo* indexes, struct CurrentDirectoryInfo* info) { if (get_words_count(indexes) != 2) { // tulis parameter cd tidak valid return; } - int index = indexes[1]; - int length = indexes[2] - indexes[1]; - - int param_indexes[INDEXES_MAX_COUNT]; + + struct IndexInfo param_indexes[INDEXES_MAX_COUNT]; reset_indexes(param_indexes); - get_buffer_indexes(buf, param_indexes, '/', index, length); + get_buffer_indexes(buf, param_indexes, '/', indexes[1].index, indexes[1].length); int i = 0; - while(i < INDEXES_MAX_COUNT-1 && param_indexes[i+1] != -1) + while(i < INDEXES_MAX_COUNT && !is_default_index(param_indexes[i])) { - int param_index = param_indexes[i]; - int param_length = param_indexes[i+1] - param_indexes[i]; - i++; - if (param_length == 1 && buf[param_index] == '.') + if (param_indexes[i].length == 1 && buf[param_indexes[i].index] == '.') { continue; } - else if (is_back_path(buf, param_index, param_length)) + else if (is_back_path(buf, param_indexes[i].index, param_indexes[i].length)) { // TODO :go to parent dir } @@ -141,6 +153,8 @@ void cd_command(char* buf, int* indexes, struct CurrentDirectoryInfo* info) { // TODO :go to target dir } + + i++; } } From 432252dda2035921c3a2d357845aff80dddb87f1 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Fri, 21 Apr 2023 21:48:42 +0700 Subject: [PATCH 004/101] refactor: add explanation comment --- src/user-shell.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/user-shell.c b/src/user-shell.c index 6abaf26..6af0e60 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -54,6 +54,7 @@ void get_buffer_indexes(char* buf, struct IndexInfo* indexes, char delimiter, in // contoh penggunaan: // buf = " 12 45 79 \0" + // diperoleh indexes = [[1, 2], [4, 2], [7, 2]] untuk array di dalam dalam format [indeks, length] int i = starting_index; int limit = i + buffer_length; From b30654e2ed25918e6d803eebdf577a95e9fbb9bc Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Sat, 22 Apr 2023 00:07:41 +0700 Subject: [PATCH 005/101] feat: add cd and ls command --- src/fat32.c | 29 ++++++++++++ src/interrupt.c | 8 +++- src/lib-header/fat32.h | 11 ++++- src/user-shell.c | 102 +++++++++++++++++++++++++++++++++-------- 4 files changed, 127 insertions(+), 23 deletions(-) diff --git a/src/fat32.c b/src/fat32.c index 25f4296..952845c 100644 --- a/src/fat32.c +++ b/src/fat32.c @@ -166,8 +166,21 @@ void init_directory_table_child(struct FAT32DirectoryTable *dir_table, } int8_t read_directory(struct FAT32DriverRequest request) { + read_clusters(&driver_state.dir_table_buf, request.parent_cluster_number, 1); + if (request.parent_cluster_number == ROOT_CLUSTER_NUMBER && memcmp("root\0\0\0\0", request.name, 8) == 0) + { + // Return error when the buffer size is insufficient + if (request.buffer_size < driver_state.dir_table_buf.table->filesize) { + return -1; + } + + // Enough size, read the cluster to the buffer + read_directory_by_entry(ROOT_CLUSTER_NUMBER, request); + return 0; + } + // If given parent cluster number isn't the head of a directory, return error if (is_dirtable_child(&driver_state.dir_table_buf)) { return 3; @@ -418,6 +431,9 @@ int8_t write(struct FAT32DriverRequest request) { // Create a directory if (is_creating_directory) { + + if (memcmp("root\0\0\0\0", request.name, 8) == 0) return 3; + create_subdirectory_from_entry(new_cluster_number, entry, request); return 0; } @@ -698,6 +714,19 @@ void read_directory_by_entry(struct FAT32DirectoryEntry *entry, //set_access_datetime(entry); } +void read_directory_by_cluster_number(uint16_t cluster_number, + struct FAT32DriverRequest req) { + uint16_t now_cluster_number = cluster_number; + uint8_t nth_cluster = 0; + do { + read_clusters(req.buf + CLUSTER_SIZE * nth_cluster, now_cluster_number, 1); + now_cluster_number = + driver_state.fat_table.cluster_map[now_cluster_number] & 0x0000FFFF; + nth_cluster++; + } while (now_cluster_number != 0xFFFF); + //set_access_datetime(entry); +} + void increment_subdir_n_of_entry(struct FAT32DirectoryTable *table) { table->table[0].n_of_entries++; } diff --git a/src/interrupt.c b/src/interrupt.c index c4369be..dcafc47 100644 --- a/src/interrupt.c +++ b/src/interrupt.c @@ -77,6 +77,8 @@ void main_interrupt_handler(struct CPURegister cpu, uint32_t int_number, struct } void syscall(struct CPURegister cpu, __attribute__((unused)) struct InterruptStack info) { + + // read if (cpu.eax == 0) { struct FAT32DriverRequest request = *(struct FAT32DriverRequest*) cpu.ebx; *((int8_t*) cpu.ecx) = read(request); @@ -92,10 +94,12 @@ void syscall(struct CPURegister cpu, __attribute__((unused)) struct InterruptSta } else if (cpu.eax == 5) { - puts((char *) cpu.ebx, cpu.ecx, cpu.edx); // Modified puts() on kernel side + puts((char *) cpu.ebx, cpu.ecx, cpu.edx); // belum diimplementasi } + // read parent directory table only with its cluster number else if (cpu.eax == 6) { - + struct FAT32DriverRequest request = *(struct FAT32DriverRequest*) cpu.ebx; + read_clusters(request.buf, request.parent_cluster_number, 1); } } diff --git a/src/lib-header/fat32.h b/src/lib-header/fat32.h index 3019cde..c9372f6 100644 --- a/src/lib-header/fat32.h +++ b/src/lib-header/fat32.h @@ -258,7 +258,7 @@ int8_t read(struct FAT32DriverRequest request); * @param request All attribute will be used for write, buffer_size == 0 then * create a folder / directory * @return Error code: 0 success - 1 file/folder already exist - 2 invalid - * parent cluster - -1 unknown + * parent cluster - 3 forbidden name - -1 unknown */ int8_t write(struct FAT32DriverRequest request); @@ -441,6 +441,15 @@ void delete_file_by_entry(struct FAT32DirectoryEntry *entry, void read_directory_by_entry(struct FAT32DirectoryEntry *entry, struct FAT32DriverRequest req); +/** + * @brief Read a directory + * + * @param cluster_number The intial cluster_number of directory + * @param req The request to which read result is to be transferred + */ +void read_directory_by_cluster_number(uint16_t cluster_number, + struct FAT32DriverRequest req); + /** * @brief Create a child cluster of a subdirectory * diff --git a/src/user-shell.c b/src/user-shell.c index 6af0e60..45e3c87 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -7,6 +7,7 @@ #define COMMAND_COUNT 12 #define DIRECTORY_NAME_LENGTH 8 #define INDEXES_MAX_COUNT SHELL_BUFFER_SIZE +#define PATH_MAX_COUNT 256 const char command_list[COMMAND_COUNT][COMMAND_MAX_SIZE] = { "cd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "ls\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", @@ -24,10 +25,10 @@ const char command_list[COMMAND_COUNT][COMMAND_MAX_SIZE] = { struct CurrentDirectoryInfo { - uint16_t parent_cluster_number; + char paths[PATH_MAX_COUNT][DIRECTORY_NAME_LENGTH]; + uint32_t current_path_count; uint16_t current_cluster_number; - char current_directory_name[8]; - + // char current_directory_name[8]; } __attribute__((packed)); struct IndexInfo { @@ -112,16 +113,6 @@ int get_words_count(struct IndexInfo* indexes) return count; } -bool is_back_path(int* buf, int starting_index, int length) -{ - for (int i = starting_index; i < starting_index+length; i++) - { - if (buf[i] != '.') return FALSE; - } - - return TRUE; -} - void cd_command(char* buf, struct IndexInfo* indexes, struct CurrentDirectoryInfo* info) { if (get_words_count(indexes) != 2) @@ -137,22 +128,95 @@ void cd_command(char* buf, struct IndexInfo* indexes, struct CurrentDirectoryInf int i = 0; + if (buf[indexes[1].index] == '/') + { + info->current_cluster_number = ROOT_CLUSTER_NUMBER; + info->current_path_count = 0; + } + while(i < INDEXES_MAX_COUNT && !is_default_index(param_indexes[i])) { if (param_indexes[i].length == 1 && buf[param_indexes[i].index] == '.') { + i++; continue; } - else if (is_back_path(buf, param_indexes[i].index, param_indexes[i].length)) + else if (param_indexes[i].length == 2 && memcmp(buf+param_indexes[i].index, "..", 2) == 0) { // TODO :go to parent dir + + if (info->current_cluster_number != ROOT_CLUSTER_NUMBER) + { + struct ClusterBuffer cl = {0}; + struct FAT32DriverRequest request = { + .buf = &cl, + .name = "\0\0\0\0\0\0\0\0", + .ext = "\0\0\0", + .parent_cluster_number = info->current_cluster_number, + .buffer_size = CLUSTER_SIZE * 5, + }; + + syscall(6, (uint32_t) &request, 0, 0); + + struct FAT32DirectoryTable* dir_table = request.buf; + + info->current_cluster_number = dir_table->table->cluster_low; + info->current_path_count--; + } } else { - // TODO :go to target dir + struct ClusterBuffer cl[5]; + + struct FAT32DriverRequest request = { + .buf = &cl, + .name = "\0\0\0\0\0\0\0\0", + .ext = "\0\0\0", + .parent_cluster_number = info->current_cluster_number, + .buffer_size = CLUSTER_SIZE * 5, + }; + + syscall(6, (uint32_t) &request, 0, 0); + + struct FAT32DirectoryTable* dir_table = request.buf; + + memcpy(request.name, info->paths[info->current_path_count-1], DIRECTORY_NAME_LENGTH); + request.parent_cluster_number = dir_table->table->cluster_low; + + int32_t retcode; + + syscall(0, (uint32_t) &request, (uint32_t) &retcode, 0); + + dir_table = request.buf; + int j = 0; + bool found = FALSE; + + while (j < dir_table->table->filesize / CLUSTER_SIZE && !found) + { + int k = 0; + + while (k < dir_table[j].table->n_of_entries && !found) + { + struct FAT32DirectoryEntry *entry = &dir_table[j].table[k]; + + if (memcmp(entry->name, buf+param_indexes[i].index, param_indexes[i].length) == 0 + && entry->attribute == ATTR_SUBDIRECTORY) + + { + info->current_cluster_number = entry->cluster_low; + memcpy(info->paths[info->current_path_count], request.name, DIRECTORY_NAME_LENGTH); + info->current_path_count++; + found = TRUE; + } + + k++; + } + + j++; + } } i++; @@ -164,7 +228,7 @@ void ls_command(uint16_t current_cluster_number, struct CurrentDirectoryInfo inf struct ClusterBuffer cl[5]; struct FAT32DriverRequest request = { .buf = &cl, - .name = info.current_directory_name, + .name = info.paths[current_cluster_number-1], .ext = "\0\0\0", .parent_cluster_number = info.current_cluster_number, .buffer_size = CLUSTER_SIZE * 5, @@ -186,8 +250,7 @@ void ls_command(uint16_t current_cluster_number, struct CurrentDirectoryInfo inf int j = 1; while(j < dirTable[i].table->n_of_entries) { - //TODO : catat nama file/dir - + //TODO : output nama file/dir j++; } @@ -206,9 +269,8 @@ int main(void) { struct CurrentDirectoryInfo current_directory_info = { - .parent_cluster_number = ROOT_CLUSTER_NUMBER, .current_cluster_number = ROOT_CLUSTER_NUMBER, - .current_directory_name = "root\0\0\0", + .current_path_count = 0, }; // fungsi atas-atas belum fix :D From 73bc309300007957bc0b5a4b95cfa0da08622061 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Sat, 22 Apr 2023 00:52:06 +0700 Subject: [PATCH 006/101] fix: remove warning --- src/external-inserter.c | 6 +++--- src/fat32.c | 4 ++-- src/interrupt.c | 8 +++++++- src/user-shell.c | 30 +++++++++++++++--------------- 4 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/external-inserter.c b/src/external-inserter.c index 76e440a..e70b1dc 100644 --- a/src/external-inserter.c +++ b/src/external-inserter.c @@ -1,10 +1,10 @@ #include #include -#include "lib-header/stdtype.h" +// #include "lib-header/stdtype.h" // Usual gcc fixed width integer type -// typedef u_int32_t uint32_t; -// typedef u_int8_t uint8_t; +typedef u_int32_t uint32_t; +typedef u_int8_t uint8_t; // Manual import from fat32.h, disk.h, & stdmem.h due some issue with size_t #define BLOCK_SIZE 512 diff --git a/src/fat32.c b/src/fat32.c index 952845c..23904d9 100644 --- a/src/fat32.c +++ b/src/fat32.c @@ -177,7 +177,7 @@ int8_t read_directory(struct FAT32DriverRequest request) { } // Enough size, read the cluster to the buffer - read_directory_by_entry(ROOT_CLUSTER_NUMBER, request); + read_directory_by_cluster_number(ROOT_CLUSTER_NUMBER, request); return 0; } @@ -433,7 +433,7 @@ int8_t write(struct FAT32DriverRequest request) { if (is_creating_directory) { if (memcmp("root\0\0\0\0", request.name, 8) == 0) return 3; - + create_subdirectory_from_entry(new_cluster_number, entry, request); return 0; } diff --git a/src/interrupt.c b/src/interrupt.c index dcafc47..8264e45 100644 --- a/src/interrupt.c +++ b/src/interrupt.c @@ -76,6 +76,11 @@ void main_interrupt_handler(struct CPURegister cpu, uint32_t int_number, struct } } +void puts(char* buf, uint32_t length, uint8_t color) +{ + +} + void syscall(struct CPURegister cpu, __attribute__((unused)) struct InterruptStack info) { // read @@ -94,7 +99,8 @@ void syscall(struct CPURegister cpu, __attribute__((unused)) struct InterruptSta } else if (cpu.eax == 5) { - puts((char *) cpu.ebx, cpu.ecx, cpu.edx); // belum diimplementasi + framebuffer_write_row(0, 0, "bruh", cpu.ecx, 0); + // puts((char *) cpu.ebx, cpu.ecx, cpu.edx); // belum diimplementasi } // read parent directory table only with its cluster number diff --git a/src/user-shell.c b/src/user-shell.c index 45e3c87..c917c3e 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -1,6 +1,7 @@ #include "lib-header/stdtype.h" #include "lib-header/fat32.h" #include "lib-header/stdmem.h" +#include "lib-header/framebuffer.h" #define SHELL_BUFFER_SIZE 256 #define COMMAND_MAX_SIZE 32 @@ -51,6 +52,13 @@ void syscall(uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx) { __asm__ volatile("int $0x30"); } +void reset_indexes(struct IndexInfo* indexes) +{ + for (int i = 0; i < INDEXES_MAX_COUNT; i++) { + indexes[i] = defaultIndexInfo; + } +} + void get_buffer_indexes(char* buf, struct IndexInfo* indexes, char delimiter, int starting_index, int buffer_length) { // contoh penggunaan: @@ -93,13 +101,6 @@ int get_command_number(char* buf, int starting_index, int command_length) { return -1; } -void reset_indexes(struct IndexInfo* indexes) -{ - for (int i = 0; i < INDEXES_MAX_COUNT; i++) { - indexes[i] = defaultIndexInfo; - } -} - bool is_default_index(struct IndexInfo index_info) { return index_info.index == -1 && index_info.length == 0; @@ -191,7 +192,7 @@ void cd_command(char* buf, struct IndexInfo* indexes, struct CurrentDirectoryInf syscall(0, (uint32_t) &request, (uint32_t) &retcode, 0); dir_table = request.buf; - int j = 0; + uint32_t j = 0; bool found = FALSE; while (j < dir_table->table->filesize / CLUSTER_SIZE && !found) @@ -228,21 +229,21 @@ void ls_command(uint16_t current_cluster_number, struct CurrentDirectoryInfo inf struct ClusterBuffer cl[5]; struct FAT32DriverRequest request = { .buf = &cl, - .name = info.paths[current_cluster_number-1], .ext = "\0\0\0", .parent_cluster_number = info.current_cluster_number, .buffer_size = CLUSTER_SIZE * 5, }; + memcpy(request.name, info.paths[current_cluster_number-1], DIRECTORY_NAME_LENGTH); + int32_t retcode; syscall(0, (uint32_t) &request, (uint32_t) &retcode, 0); if (retcode == 0) { - struct FAT32DirectoryTable dirTable[5] = request.buf; + struct FAT32DirectoryTable* dirTable = request.buf; int i = 0; - int entry_count = 0; int dir_table_count = dirTable->table->filesize / CLUSTER_SIZE; while (i < dir_table_count) @@ -262,10 +263,7 @@ void ls_command(uint16_t current_cluster_number, struct CurrentDirectoryInfo inf int main(void) { char buf[SHELL_BUFFER_SIZE]; - int word_indexes[INDEXES_MAX_COUNT]; - // char paths[PATH_MAX_COUNT][8]; - // int current_path_count = 0; - // uint16_t parent_cluster_number = ROOT_CLUSTER_NUMBER; + struct IndexInfo word_indexes[INDEXES_MAX_COUNT]; struct CurrentDirectoryInfo current_directory_info = { @@ -278,7 +276,9 @@ int main(void) { while (TRUE) { reset_indexes(word_indexes); + if (current_directory_info.current_cluster_number) { + } syscall(4, (uint32_t) buf, SHELL_BUFFER_SIZE, 0); syscall(5, (uint32_t) buf, SHELL_BUFFER_SIZE, 0xF); // syscall ini belum implement fungsi put } From 916565eda8ff65586048cecc4f898c0b7a20d123 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Sun, 23 Apr 2023 08:09:19 +0700 Subject: [PATCH 007/101] feat: add puts function --- src/interrupt.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/interrupt.c b/src/interrupt.c index 8264e45..175fa8a 100644 --- a/src/interrupt.c +++ b/src/interrupt.c @@ -78,7 +78,48 @@ void main_interrupt_handler(struct CPURegister cpu, uint32_t int_number, struct void puts(char* buf, uint32_t length, uint8_t color) { + int counter = 0; + while (counter < length) + { + // Getting position cursor + uint16_t position_cursor = get_cursor_position(); + uint8_t row = position_cursor / 80; + uint8_t col = position_cursor % 80; + + if (buf[counter] == '\n'){ + // If enter is pressed + if(row < 24){ + // Move cursor to newline + framebuffer_set_cursor(row + 1, 0); + } + + else { + scroll_behavior(); + framebuffer_set_cursor(row, 0); + } + } + + else if (buf[counter] != '\0') + { + framebuffer_write(row, col, buf[counter], 0xF, 0); + // Handle wrapping behaviour + if(col < 79){ + framebuffer_set_cursor(row, col + 1); + } + + else if(row < 24) { + framebuffer_set_cursor(row + 1, 0); + } + + else { + scroll_behavior(); + framebuffer_set_cursor(row, 0); + } + } + + counter++; + } } void syscall(struct CPURegister cpu, __attribute__((unused)) struct InterruptStack info) { From c900cd614a8c6a171fc6639979da0e73dd8da656 Mon Sep 17 00:00:00 2001 From: sozyGithub Date: Sun, 23 Apr 2023 19:48:50 +0700 Subject: [PATCH 008/101] feat: mkdir shell cmd --- src/user-shell.c | 243 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 175 insertions(+), 68 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index c917c3e..fc488fe 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -3,12 +3,12 @@ #include "lib-header/stdmem.h" #include "lib-header/framebuffer.h" -#define SHELL_BUFFER_SIZE 256 -#define COMMAND_MAX_SIZE 32 -#define COMMAND_COUNT 12 +#define SHELL_BUFFER_SIZE 256 +#define COMMAND_MAX_SIZE 32 +#define COMMAND_COUNT 12 #define DIRECTORY_NAME_LENGTH 8 -#define INDEXES_MAX_COUNT SHELL_BUFFER_SIZE -#define PATH_MAX_COUNT 256 +#define INDEXES_MAX_COUNT SHELL_BUFFER_SIZE +#define PATH_MAX_COUNT 256 const char command_list[COMMAND_COUNT][COMMAND_MAX_SIZE] = { "cd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "ls\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", @@ -32,7 +32,8 @@ struct CurrentDirectoryInfo // char current_directory_name[8]; } __attribute__((packed)); -struct IndexInfo { +struct IndexInfo +{ int index; int length; } __attribute__((packed)); @@ -42,24 +43,35 @@ struct IndexInfo defaultIndexInfo = { .length = 0, }; -void syscall(uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx) { - __asm__ volatile("mov %0, %%ebx" : /* */ : "r"(ebx)); - __asm__ volatile("mov %0, %%ecx" : /* */ : "r"(ecx)); - __asm__ volatile("mov %0, %%edx" : /* */ : "r"(edx)); - __asm__ volatile("mov %0, %%eax" : /* */ : "r"(eax)); +void syscall(uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx) +{ + __asm__ volatile("mov %0, %%ebx" + : /* */ + : "r"(ebx)); + __asm__ volatile("mov %0, %%ecx" + : /* */ + : "r"(ecx)); + __asm__ volatile("mov %0, %%edx" + : /* */ + : "r"(edx)); + __asm__ volatile("mov %0, %%eax" + : /* */ + : "r"(eax)); // Note : gcc usually use %eax as intermediate register, // so it need to be the last one to mov __asm__ volatile("int $0x30"); } -void reset_indexes(struct IndexInfo* indexes) +void reset_indexes(struct IndexInfo *indexes) { - for (int i = 0; i < INDEXES_MAX_COUNT; i++) { + for (int i = 0; i < INDEXES_MAX_COUNT; i++) + { indexes[i] = defaultIndexInfo; } } -void get_buffer_indexes(char* buf, struct IndexInfo* indexes, char delimiter, int starting_index, int buffer_length) { +void get_buffer_indexes(char *buf, struct IndexInfo *indexes, char delimiter, int starting_index, int buffer_length) +{ // contoh penggunaan: // buf = " 12 45 79 \0" @@ -68,18 +80,21 @@ void get_buffer_indexes(char* buf, struct IndexInfo* indexes, char delimiter, in int i = starting_index; int limit = i + buffer_length; int count = 0; - + reset_indexes(indexes); while (i < limit && buf[i] != '\0') { - while(i < limit && buf[i] == delimiter && buf[i] != '\0') i++; + while (i < limit && buf[i] == delimiter && buf[i] != '\0') + i++; - if (i >= limit || buf[i] == '\0') break; + if (i >= limit || buf[i] == '\0') + break; indexes[count].index = i; - while(i < limit && buf[i] != delimiter && buf[i] != '\0') i++; + while (i < limit && buf[i] != delimiter && buf[i] != '\0') + i++; indexes[count].length = (i - indexes[count].index); @@ -87,15 +102,18 @@ void get_buffer_indexes(char* buf, struct IndexInfo* indexes, char delimiter, in } } -int get_command_number(char* buf, int starting_index, int command_length) { +int get_command_number(char *buf, int starting_index, int command_length) +{ // return -1 if command not found // return command_list number if found - if (command_length > COMMAND_MAX_SIZE) return -1; + if (command_length > COMMAND_MAX_SIZE) + return -1; for (int i = 0; i < COMMAND_COUNT; i++) { - if (memcmp(buf + starting_index, command_list[i], command_length) == 0) return i; + if (memcmp(buf + starting_index, command_list[i], command_length) == 0) + return i; } return -1; @@ -106,22 +124,23 @@ bool is_default_index(struct IndexInfo index_info) return index_info.index == -1 && index_info.length == 0; } -int get_words_count(struct IndexInfo* indexes) +int get_words_count(struct IndexInfo *indexes) { int count = 0; - while (count < INDEXES_MAX_COUNT && !is_default_index(indexes[count])) count++; + while (count < INDEXES_MAX_COUNT && !is_default_index(indexes[count])) + count++; return count; } -void cd_command(char* buf, struct IndexInfo* indexes, struct CurrentDirectoryInfo* info) +void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInfo *info) { if (get_words_count(indexes) != 2) { // tulis parameter cd tidak valid return; } - + struct IndexInfo param_indexes[INDEXES_MAX_COUNT]; reset_indexes(param_indexes); @@ -129,13 +148,13 @@ void cd_command(char* buf, struct IndexInfo* indexes, struct CurrentDirectoryInf int i = 0; - if (buf[indexes[1].index] == '/') + if (buf[indexes[1].index] == '/') { info->current_cluster_number = ROOT_CLUSTER_NUMBER; info->current_path_count = 0; } - while(i < INDEXES_MAX_COUNT && !is_default_index(param_indexes[i])) + while (i < INDEXES_MAX_COUNT && !is_default_index(param_indexes[i])) { if (param_indexes[i].length == 1 && buf[param_indexes[i].index] == '.') @@ -144,7 +163,7 @@ void cd_command(char* buf, struct IndexInfo* indexes, struct CurrentDirectoryInf continue; } - else if (param_indexes[i].length == 2 && memcmp(buf+param_indexes[i].index, "..", 2) == 0) + else if (param_indexes[i].length == 2 && memcmp(buf + param_indexes[i].index, "..", 2) == 0) { // TODO :go to parent dir @@ -152,16 +171,16 @@ void cd_command(char* buf, struct IndexInfo* indexes, struct CurrentDirectoryInf { struct ClusterBuffer cl = {0}; struct FAT32DriverRequest request = { - .buf = &cl, - .name = "\0\0\0\0\0\0\0\0", - .ext = "\0\0\0", + .buf = &cl, + .name = "\0\0\0\0\0\0\0\0", + .ext = "\0\0\0", .parent_cluster_number = info->current_cluster_number, - .buffer_size = CLUSTER_SIZE * 5, + .buffer_size = CLUSTER_SIZE * 5, }; - syscall(6, (uint32_t) &request, 0, 0); + syscall(6, (uint32_t)&request, 0, 0); - struct FAT32DirectoryTable* dir_table = request.buf; + struct FAT32DirectoryTable *dir_table = request.buf; info->current_cluster_number = dir_table->table->cluster_low; info->current_path_count--; @@ -173,25 +192,25 @@ void cd_command(char* buf, struct IndexInfo* indexes, struct CurrentDirectoryInf struct ClusterBuffer cl[5]; struct FAT32DriverRequest request = { - .buf = &cl, - .name = "\0\0\0\0\0\0\0\0", - .ext = "\0\0\0", + .buf = &cl, + .name = "\0\0\0\0\0\0\0\0", + .ext = "\0\0\0", .parent_cluster_number = info->current_cluster_number, - .buffer_size = CLUSTER_SIZE * 5, + .buffer_size = CLUSTER_SIZE * 5, }; - syscall(6, (uint32_t) &request, 0, 0); + syscall(6, (uint32_t)&request, 0, 0); - struct FAT32DirectoryTable* dir_table = request.buf; + struct FAT32DirectoryTable *dir_table = request.buf; - memcpy(request.name, info->paths[info->current_path_count-1], DIRECTORY_NAME_LENGTH); + memcpy(request.name, info->paths[info->current_path_count - 1], DIRECTORY_NAME_LENGTH); request.parent_cluster_number = dir_table->table->cluster_low; int32_t retcode; - syscall(0, (uint32_t) &request, (uint32_t) &retcode, 0); + syscall(0, (uint32_t)&request, (uint32_t)&retcode, 0); - dir_table = request.buf; + dir_table = request.buf; uint32_t j = 0; bool found = FALSE; @@ -202,13 +221,12 @@ void cd_command(char* buf, struct IndexInfo* indexes, struct CurrentDirectoryInf while (k < dir_table[j].table->n_of_entries && !found) { struct FAT32DirectoryEntry *entry = &dir_table[j].table[k]; - - if (memcmp(entry->name, buf+param_indexes[i].index, param_indexes[i].length) == 0 - && entry->attribute == ATTR_SUBDIRECTORY) - + + if (memcmp(entry->name, buf + param_indexes[i].index, param_indexes[i].length) == 0 && entry->attribute == ATTR_SUBDIRECTORY) + { info->current_cluster_number = entry->cluster_low; - memcpy(info->paths[info->current_path_count], request.name, DIRECTORY_NAME_LENGTH); + memcpy(info->paths[info->current_path_count], request.name, DIRECTORY_NAME_LENGTH); info->current_path_count++; found = TRUE; } @@ -228,20 +246,21 @@ void ls_command(uint16_t current_cluster_number, struct CurrentDirectoryInfo inf { struct ClusterBuffer cl[5]; struct FAT32DriverRequest request = { - .buf = &cl, - .ext = "\0\0\0", + .buf = &cl, + .ext = "\0\0\0", .parent_cluster_number = info.current_cluster_number, - .buffer_size = CLUSTER_SIZE * 5, + .buffer_size = CLUSTER_SIZE * 5, }; - memcpy(request.name, info.paths[current_cluster_number-1], DIRECTORY_NAME_LENGTH); + memcpy(request.name, info.paths[current_cluster_number - 1], DIRECTORY_NAME_LENGTH); int32_t retcode; - syscall(0, (uint32_t) &request, (uint32_t) &retcode, 0); + syscall(0, (uint32_t)&request, (uint32_t)&retcode, 0); - if (retcode == 0) { - struct FAT32DirectoryTable* dirTable = request.buf; + if (retcode == 0) + { + struct FAT32DirectoryTable *dirTable = request.buf; int i = 0; int dir_table_count = dirTable->table->filesize / CLUSTER_SIZE; @@ -249,9 +268,9 @@ void ls_command(uint16_t current_cluster_number, struct CurrentDirectoryInfo inf while (i < dir_table_count) { int j = 1; - while(j < dirTable[i].table->n_of_entries) + while (j < dirTable[i].table->n_of_entries) { - //TODO : output nama file/dir + // TODO : output nama file/dir j++; } @@ -260,29 +279,117 @@ void ls_command(uint16_t current_cluster_number, struct CurrentDirectoryInfo inf } } -int main(void) { +void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInfo *info) +{ + if (get_words_count(indexes) != 2) + { + // tulis parameter cd tidak valid + return; + } + + // convert "mkdir" to "cd " + buf[0] = 'c'; // m + buf[1] = 'd'; // k + for (int i = indexes[0].index + 2; i < indexes[0].length; i++) + { + buf[i] = ' '; // dir + } + + struct IndexInfo new_indexes[INDEXES_MAX_COUNT]; + reset_indexes(new_indexes); + // [cd] [intial_path] + get_buffer_indexes(buf, new_indexes, ' ', indexes[0].index, indexes[0].length + indexes[1].length); + + struct IndexInfo new_path_indexes[INDEXES_MAX_COUNT]; + reset_indexes(new_path_indexes); + // [path_segment_1] [path_segment_2] [path_segment_3] ... + get_buffer_indexes(buf, new_path_indexes, '/', new_indexes[1].index, new_indexes[1].length); + + int i = 0; + int target_buf_length = 6; // "cd " + while (!is_default_deinx(new_path_indexes[i + 1])) + { + target_buf_length += new_path_indexes[i].length; + } + + char *new_dir_name; + for (int i = target_buf_length; i < new_path_indexes[i].length; i++) + { + if (i == 8) + { + // return invalid new_dir_name + } + new_dir_name[i - target_buf_length] = buf[i]; + } + + // temporary CurrentDirectoryInfo for creating the new directory + struct CurrentDirectoryInfo target_directory = { + .current_cluster_number = info->current_cluster_number, + .current_path_count = info->current_path_count, + }; + + memcpy(target_directory.paths, info->paths, sizeof(info->paths)); + + // check if path_segment count > 1 + if (!is_default_index(new_path_indexes[1])) + { + char *target_buff; + for (int i = 0; i < target_buf_length; i++) + { + target_buff[i] = buf[i]; + } + // call cd command to move the directory + cd_command(target_buff, new_indexes, &target_directory); + } + + // create new directory in the target_directory + struct ClusterBuffer cl[5]; + struct FAT32DriverRequest write_request = { + .buf = &cl, + .ext = "\0\0\0", + .name = new_dir_name, + .parent_cluster_number = target_directory.current_cluster_number, + .buffer_size = CLUSTER_SIZE * 5, + }; + + int32_t retcode; + + syscall(2, (uint32_t)&write_request, (uint32_t)&retcode, 0); + + if (retcode == 0) + { + // mkdir command success + } + else + { + // directory with the corresponding name already exist. + } +} + +int main(void) +{ char buf[SHELL_BUFFER_SIZE]; struct IndexInfo word_indexes[INDEXES_MAX_COUNT]; struct CurrentDirectoryInfo current_directory_info = - { - .current_cluster_number = ROOT_CLUSTER_NUMBER, - .current_path_count = 0, - }; + { + .current_cluster_number = ROOT_CLUSTER_NUMBER, + .current_path_count = 0, + }; // fungsi atas-atas belum fix :D - while (TRUE) { + while (TRUE) + { reset_indexes(word_indexes); - if (current_directory_info.current_cluster_number) { - + if (current_directory_info.current_cluster_number) + { } - syscall(4, (uint32_t) buf, SHELL_BUFFER_SIZE, 0); - syscall(5, (uint32_t) buf, SHELL_BUFFER_SIZE, 0xF); // syscall ini belum implement fungsi put + syscall(4, (uint32_t)buf, SHELL_BUFFER_SIZE, 0); + syscall(5, (uint32_t)buf, SHELL_BUFFER_SIZE, 0xF); // syscall ini belum implement fungsi put } return 0; } - From 88241a55682df8c560d9aad550ee01c8eecb15af Mon Sep 17 00:00:00 2001 From: sozyGithub Date: Wed, 26 Apr 2023 06:17:30 +0700 Subject: [PATCH 009/101] feat: cat and whereis cmd --- src/user-shell.c | 220 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 215 insertions(+), 5 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index fc488fe..04e03b6 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -283,7 +283,7 @@ void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory { if (get_words_count(indexes) != 2) { - // tulis parameter cd tidak valid + // tulis parameter mkdir tidak valid return; } @@ -307,12 +307,12 @@ void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory int i = 0; int target_buf_length = 6; // "cd " - while (!is_default_deinx(new_path_indexes[i + 1])) + while (!is_default_index(new_path_indexes[i + 1])) { target_buf_length += new_path_indexes[i].length; } - char *new_dir_name; + char new_dir_name[8]; for (int i = target_buf_length; i < new_path_indexes[i].length; i++) { if (i == 8) @@ -333,13 +333,15 @@ void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory // check if path_segment count > 1 if (!is_default_index(new_path_indexes[1])) { - char *target_buff; + char target_buff[target_buf_length]; for (int i = 0; i < target_buf_length; i++) { target_buff[i] = buf[i]; } // call cd command to move the directory cd_command(target_buff, new_indexes, &target_directory); + + // TODO: handle failed cd } // create new directory in the target_directory @@ -347,11 +349,12 @@ void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory struct FAT32DriverRequest write_request = { .buf = &cl, .ext = "\0\0\0", - .name = new_dir_name, .parent_cluster_number = target_directory.current_cluster_number, .buffer_size = CLUSTER_SIZE * 5, }; + memcpy(write_request.name, new_dir_name, sizeof(new_dir_name)); + int32_t retcode; syscall(2, (uint32_t)&write_request, (uint32_t)&retcode, 0); @@ -366,6 +369,213 @@ void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory } } +void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInfo *info) +{ + if (get_words_count(indexes) != 2) + { + // tulis parameter cat tidak valid + return; + } + + // convert "cat" to "cd " + buf[0] = 'c'; // c + buf[1] = 'd'; // a + buf[2] = ' '; // t + + struct IndexInfo new_indexes[INDEXES_MAX_COUNT]; + reset_indexes(new_indexes); + // [cd] [intial_path] + get_buffer_indexes(buf, new_indexes, ' ', indexes[0].index, indexes[0].length + indexes[1].length); + + struct IndexInfo new_path_indexes[INDEXES_MAX_COUNT]; + reset_indexes(new_path_indexes); + // [path_segment_1] [path_segment_2] [path_segment_3] ... + get_buffer_indexes(buf, new_path_indexes, '/', new_indexes[1].index, new_indexes[1].length); + + int i = 0; + int target_buf_length = 6; // "cd " + while (!is_default_index(new_path_indexes[i + 1])) + { + target_buf_length += new_path_indexes[i].length; + } + + char *target_file_name; + for (int i = target_buf_length; i < new_path_indexes[i].length; i++) + { + if (i == 8) + { + // return invalid target_file_name + } + target_file_name[i - target_buf_length] = buf[i]; + } + + // temporary CurrentDirectoryInfo for creating the new directory + struct CurrentDirectoryInfo target_directory = { + .current_cluster_number = info->current_cluster_number, + .current_path_count = info->current_path_count, + }; + + memcpy(target_directory.paths, info->paths, sizeof(info->paths)); + + // check if path_segment count > 1 + if (!is_default_index(new_path_indexes[1])) + { + char *target_buff; + for (int i = 0; i < target_buf_length; i++) + { + target_buff[i] = buf[i]; + } + // call cd command to move the directory + cd_command(target_buff, new_indexes, &target_directory); + + // TODO: handle failed cd + } + + // read the file from FATtable + struct ClusterBuffer cl[5]; + struct FAT32DriverRequest read_request = { + .buf = &cl, + .ext = "\0\0\0", + .name = target_file_name, + .parent_cluster_number = target_directory.current_cluster_number, + .buffer_size = CLUSTER_SIZE * 5, + }; + + int32_t retcode; + + syscall(0, (uint32_t)&read_request, (uint32_t)&retcode, 0); + + if (retcode == 0) + { + struct FAT32DirectoryTable *dir_table = read_request.buf; + + // TODO: Print buffer contents to the screen. + } + else + { + // file does not exist. + } +} +/** + * @param target_name file or folder name + * @param parent_cluster_number parent cluster number for the corresponding folder + * + * @return 0 : target_name not found; + * parent_cluster_number : target_name found at file or folder with parent_cluster_number; + */ +uint32_t traverse_directories(char *target_name, uint32_t parent_cluster_number) +{ + bool is_found = 0; + struct ClusterBuffer cl[10]; + struct FAT32DriverRequest read_folder_request = { + .buf = &cl, + .ext = "\0\0\0", + .parent_cluster_number = parent_cluster_number, + .buffer_size = CLUSTER_SIZE * 10, + }; + + memcpy(read_folder_request.name, target_name, sizeof(target_name)); + + int32_t retcode; + syscall(1, (uint32_t)&read_folder_request, (uint32_t)&retcode, 0); + + if (retcode == 0) + { + struct FAT32DirectoryTable *dir_table = read_folder_request.buf; + + uint32_t counter_entry = 0; + for (uint32_t i = 0; i < 10 && !is_found && counter_entry < dir_table[0].table[0].n_of_entries; i++) + { + for (uint32_t j = 1; j < CLUSTER_SIZE / sizeof(struct FAT32DirectoryEntry) && !is_found && counter_entry < dir_table[0].table[0].n_of_entries; i++) + { + counter_entry++; + if (memcmp(dir_table[i].table[j].name, target_name, sizeof(target_name)) == 0) + { + is_found = parent_cluster_number; + } + else if (dir_table[i].table[j].attribute == ATTR_SUBDIRECTORY) + { + is_found = traverse_directories(target_name, (dir_table[i].table[j].cluster_high << 16) + + dir_table[i].table[j].cluster_low); + } + } + } + } + + return is_found; +} + +/** + * Calling syscall type-5 for printing the path after whereis command + * + * @param parent_cluster_number folder or file parent_cluster_number + * + * @return - + */ +void print_path(uint32_t cluster_number) +{ + // root found - base condition + if (cluster_number == ROOT_CLUSTER_NUMBER) + { + syscall(5, (uint32_t) "/", SHELL_BUFFER_SIZE, 0xF); + return; + } + + struct ClusterBuffer cl[5]; + struct FAT32DriverRequest read_folder_request = { + .buf = &cl, + .ext = "\0\0\0", + .parent_cluster_number = cluster_number, + .buffer_size = CLUSTER_SIZE * 5, + }; + + int32_t retcode; + syscall(6, (uint32_t)&read_folder_request, (uint32_t)&retcode, 0); + + if (retcode == 0) + { + struct FAT32DirectoryTable *dir_table = read_folder_request.buf; + + print_path((dir_table->table->cluster_high << 16) + dir_table->table->cluster_low); + syscall(5, (uint32_t) "/", SHELL_BUFFER_SIZE, 0xF); + syscall(5, (uint32_t)dir_table->table->name, SHELL_BUFFER_SIZE, 0xF); + } +} + +void whereis_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInfo *info) +{ + if (get_words_count(indexes) != 2) + { + syscall(5, (uint32_t) "Invalid command!", SHELL_BUFFER_SIZE, 0xF); + return; + } + + char target_name[indexes[1].length]; + for (uint32_t i = 0; i < indexes[1].length; i++) + { + target_name[i] = buf[i + indexes[1].index]; + } + + if (memcmp(target_name, "root", 4) == 0) + { + syscall(5, (uint32_t) "root: /", SHELL_BUFFER_SIZE, 0xF); + return; + } + + uint32_t parent_cluster_number = traverse_directories(target_name, ROOT_CLUSTER_NUMBER); + + if (parent_cluster_number == 0) + { + syscall(5, (uint32_t) "File or folder not found!\n", SHELL_BUFFER_SIZE, 0xF); + return; + } + + // print the full path + syscall(5, (uint32_t)target_name, SHELL_BUFFER_SIZE, 0xF); + syscall(5, (uint32_t) ": ", SHELL_BUFFER_SIZE, 0xF); + print_path(parent_cluster_number); +} + int main(void) { From 8d65a36c050c4ef915f822a703a114ad539b4aea Mon Sep 17 00:00:00 2001 From: sozyGithub Date: Wed, 26 Apr 2023 08:24:41 +0700 Subject: [PATCH 010/101] fix: syscal-5 invocation on cmd --- src/user-shell.c | 64 ++++++++++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index c2137ef..a49855a 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -66,7 +66,7 @@ void syscall(uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx) void print_newline() { char newl[1] = "\n"; - syscall(5, (uint32_t) newl, 1, 0xF); + syscall(5, (uint32_t)newl, 1, 0xF); } void reset_indexes(struct IndexInfo *indexes) @@ -164,7 +164,7 @@ void copy_directory_info(struct CurrentDirectoryInfo *dest, struct CurrentDirect * 1 - if file does not have extension, * 2 - if file has no name * 3 - if file name or extension is too long -*/ + */ int split_filename_extension(char *filename, int filename_length, char *name, char *extension) { // parse filename to name and extension @@ -173,17 +173,21 @@ int split_filename_extension(char *filename, int filename_length, char *name, ch int words_count = get_words_count(temp_index); - if(words_count == 1) { - if(temp_index[0].index == 0) return 1; // filename has no extension - if(temp_index[0].index > 0) return 2; // file has no name (why?) + if (words_count == 1) + { + if (temp_index[0].index == 0) + return 1; // filename has no extension + if (temp_index[0].index > 0) + return 2; // file has no name (why?) } - int last_word_starting_index = temp_index[words_count-1].index; - int last_word_length = temp_index[words_count-1].length; + int last_word_starting_index = temp_index[words_count - 1].index; + int last_word_length = temp_index[words_count - 1].length; // starting from 0 to (last_word_starting_index - 2) is file name int name_length = last_word_starting_index - 1; // therefore (last_word_starting_index - 2) + 1 is length of name - - if(name_length > DIRECTORY_NAME_LENGTH || last_word_length > 3) return 3; + + if (name_length > DIRECTORY_NAME_LENGTH || last_word_length > 3) + return 3; // copy name memcpy(name, filename, name_length); // copy extension @@ -248,8 +252,8 @@ void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf if (param_indexes[i].length > DIRECTORY_NAME_LENGTH) { char msg[] = "Directory name is too long: "; - syscall(5, (uint32_t) msg, 29, 0xF); - syscall(5,(uint32_t) buf + param_indexes[i].index, param_indexes[i].length, 0xF); + syscall(5, (uint32_t)msg, 29, 0xF); + syscall(5, (uint32_t)buf + param_indexes[i].index, param_indexes[i].length, 0xF); print_newline(); return; @@ -276,10 +280,10 @@ void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf syscall(1, (uint32_t)&request, (uint32_t)&retcode, 0); if (retcode != 0) - { + { char msg[] = "Failed to read directory: "; - syscall(5, (uint32_t) msg, 27, 0xF); - syscall(5, (uint32_t) request.name, DIRECTORY_NAME_LENGTH, 0xF); + syscall(5, (uint32_t)msg, 27, 0xF); + syscall(5, (uint32_t)request.name, DIRECTORY_NAME_LENGTH, 0xF); print_newline(); if (retcode == 1) @@ -287,11 +291,11 @@ void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf char errorMsg[] = "Error: not a folder\n"; syscall(5, (uint32_t)errorMsg, 21, 0xF); } - + else if (retcode == 2) { char errorMsg[] = "Error: directory not found\n"; - syscall(5, (uint32_t) errorMsg, 21, 0xF); + syscall(5, (uint32_t)errorMsg, 21, 0xF); } return; @@ -402,13 +406,13 @@ void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory if (new_path_indexes[i].length > 8) { - char msg[] = "Invalid new directory name! Maximum 7 characters!"; + char msg[] = "Invalid new directory name! Maximum 7 characters!\n"; - syscall(5, (uint32_t) msg, SHELL_BUFFER_SIZE, 0xF); + syscall(5, (uint32_t)msg, 50, 0xF); return; } - char new_dir_name[8]; + char new_dir_name[new_path_indexes[i].length]; for (int j = target_buf_length; j < target_buf_length + new_path_indexes[i].length; j++) { new_dir_name[j - target_buf_length] = buf[j]; @@ -486,7 +490,7 @@ void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryIn i++; } - char target_file_name[8]; + char target_file_name[new_path_indexes[i].length]; for (int j = target_buf_length; j < target_buf_length + new_path_indexes[i].length; j++) { target_file_name[j - target_buf_length] = buf[j]; @@ -500,7 +504,7 @@ void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryIn // check if path_segment count > 1 if (!is_default_index(new_path_indexes[1])) { - char *target_buff; + char target_buff[target_buf_length]; for (int i = 0; i < target_buf_length; i++) { target_buff[i] = buf[i]; @@ -528,11 +532,13 @@ void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryIn if (retcode == 0) { - syscall(5, (uint32_t)read_request.buf, SHELL_BUFFER_SIZE, 0xF); + syscall(5, (uint32_t)read_request.buf, read_request.buffer_size, 0xF); + print_newline(); } else { - syscall(5, (uint32_t) "File not found", SHELL_BUFFER_SIZE, 0xF); + syscall(5, (uint32_t) "File not found", 14, 0xF); + print_newline(); } } /** @@ -596,7 +602,7 @@ void print_path(uint32_t cluster_number) // root found - base condition if (cluster_number == ROOT_CLUSTER_NUMBER) { - syscall(5, (uint32_t) "/", SHELL_BUFFER_SIZE, 0xF); + syscall(5, (uint32_t) "/", 1, 0xF); return; } @@ -616,12 +622,12 @@ void print_path(uint32_t cluster_number) struct FAT32DirectoryTable *dir_table = read_folder_request.buf; print_path((dir_table->table->cluster_high << 16) + dir_table->table->cluster_low); - syscall(5, (uint32_t) "/", SHELL_BUFFER_SIZE, 0xF); - syscall(5, (uint32_t)dir_table->table->name, SHELL_BUFFER_SIZE, 0xF); + syscall(5, (uint32_t) "/", 1, 0xF); + syscall(5, (uint32_t)dir_table->table->name, 8, 0xF); + print_newline(); } } - int main(void) { const int DIRECTORY_DISPLAY_OFFSET = 23; @@ -668,7 +674,7 @@ int main(void) if (commandNumber == -1) { char msg[] = "Command not found!\n"; - syscall(5, (uint32_t) msg, 19, 0xF); + syscall(5, (uint32_t)msg, 19, 0xF); } else @@ -682,7 +688,7 @@ int main(void) else if (argsCount == 2) cd_command(buf, word_indexes + 1, ¤t_directory_info); else - syscall(5, (uint32_t) too_many_args_msg, 20, 0xF); + syscall(5, (uint32_t)too_many_args_msg, 20, 0xF); } if (commandNumber == 1) From 7599f78074adc9d0f96c0e95ea59282f9a02ec7d Mon Sep 17 00:00:00 2001 From: sozyGithub Date: Wed, 26 Apr 2023 08:40:20 +0700 Subject: [PATCH 011/101] fix: cat cmd syscal req ext --- src/user-shell.c | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index a49855a..d8ff062 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -10,6 +10,8 @@ #define INDEXES_MAX_COUNT SHELL_BUFFER_SIZE #define PATH_MAX_COUNT 256 +#define EMPTY_EXTENSION "\0\0\0" +#define EMPTY_NAME "\0\0\0\0\0\0\0\0" const char command_list[COMMAND_COUNT][COMMAND_MAX_SIZE] = { "cd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "ls\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", @@ -44,6 +46,12 @@ struct IndexInfo defaultIndexInfo = { .length = 0, }; +struct ParseString +{ + char *word; + int length; +} __attribute__((packed)); + void syscall(uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx) { __asm__ volatile("mov %0, %%ebx" @@ -165,7 +173,9 @@ void copy_directory_info(struct CurrentDirectoryInfo *dest, struct CurrentDirect * 2 - if file has no name * 3 - if file name or extension is too long */ -int split_filename_extension(char *filename, int filename_length, char *name, char *extension) +int split_filename_extension(char *filename, int filename_length, + struct ParseString *name, + struct ParseString *extension) { // parse filename to name and extension struct IndexInfo temp_index[INDEXES_MAX_COUNT]; @@ -189,15 +199,16 @@ int split_filename_extension(char *filename, int filename_length, char *name, ch if (name_length > DIRECTORY_NAME_LENGTH || last_word_length > 3) return 3; // copy name - memcpy(name, filename, name_length); + memcpy(name->word, filename, name_length); + name->length = name_length; // copy extension - memcpy(extension, &filename[last_word_starting_index], last_word_length); + memcpy(extension->word, &filename[last_word_starting_index], last_word_length); + extension->length = last_word_length; return 0; } void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInfo *info) { - struct CurrentDirectoryInfo temp_info = {}; copy_directory_info(&temp_info, info); @@ -444,7 +455,7 @@ void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory struct ClusterBuffer cl[5]; struct FAT32DriverRequest write_request = { .buf = &cl, - .ext = "\0\0\0", + .ext = EMPTY_EXTENSION, .parent_cluster_number = target_directory.current_cluster_number, .buffer_size = CLUSTER_SIZE * 5, }; @@ -490,7 +501,8 @@ void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryIn i++; } - char target_file_name[new_path_indexes[i].length]; + int target_file_name_length = new_path_indexes[i].length; + char target_file_name[target_file_name_length]; for (int j = target_buf_length; j < target_buf_length + new_path_indexes[i].length; j++) { target_file_name[j - target_buf_length] = buf[j]; @@ -519,12 +531,21 @@ void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryIn struct ClusterBuffer cl[5]; struct FAT32DriverRequest read_request = { .buf = &cl, - .ext = "\0\0\0", // TODO .parent_cluster_number = target_directory.current_cluster_number, .buffer_size = CLUSTER_SIZE * 5, }; + struct ParseString target_file_name_parsed; + struct ParseString target_file_name_extension; + int split_result = split_filename_extension(target_file_name, target_file_name_length, &target_file_name_parsed, &target_file_name_extension); + memcpy(read_request.name, target_file_name, sizeof(target_file_name)); + if (split_result != 0 && split_result != 1) + { + syscall(5, (uint32_t) "Invalid command!", 16, 0xF); + return; + } + memcpy(read_request.ext, target_file_name_extension.word, target_file_name_extension.length); int32_t retcode; @@ -542,6 +563,8 @@ void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryIn } } /** + * Traverse all directories from ROOT to find a folder or file with name equals to target_name + * * @param target_name file or folder name * @param parent_cluster_number parent cluster number for the corresponding folder * From 247e141ccb8fb024f9720c2edf7d1be3fb988932 Mon Sep 17 00:00:00 2001 From: sozyGithub Date: Wed, 26 Apr 2023 11:14:04 +0700 Subject: [PATCH 012/101] rfc: parse path for cd --- src/user-shell.c | 113 +++++++++++++++++++++++++++-------------------- 1 file changed, 64 insertions(+), 49 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index 8112526..20fac6f 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -9,12 +9,11 @@ #define DIRECTORY_NAME_LENGTH 8 #define INDEXES_MAX_COUNT SHELL_BUFFER_SIZE #define PATH_MAX_COUNT 256 -#define MAX_FILE_BUFFER_CLUSTER_SIZE 512 // take arbitrary size of 512 cluster = 512 * 4 * 512 B = 1MB +#define MAX_FILE_BUFFER_CLUSTER_SIZE 512 // take arbitrary size of 512 cluster = 512 * 4 * 512 B = 1MB #define EMPTY_EXTENSION "\0\0\0" #define EMPTY_NAME "\0\0\0\0\0\0\0\0" -#define EMPTY_EXTENSION "\0\0\0" -#define EMPTY_NAME "\0\0\0\0\0\0\0\0" + const char command_list[COMMAND_COUNT][COMMAND_MAX_SIZE] = { "cd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "ls\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", @@ -46,8 +45,7 @@ struct IndexInfo struct IndexInfo defaultIndexInfo = { .index = -1, - .length = 0 -}; + .length = 0}; struct ParseString { @@ -91,7 +89,6 @@ void reset_indexes(struct IndexInfo *indexes, uint32_t length) i++; } - } void reset_buffer(char *buf, int length) @@ -168,7 +165,8 @@ void copy_directory_info(struct CurrentDirectoryInfo *dest, struct CurrentDirect memcpy(dest->paths, source->paths, PATH_MAX_COUNT * DIRECTORY_NAME_LENGTH); } -void set_ParseString(struct ParseString *parse_string, char *str, int size) { +void set_ParseString(struct ParseString *parse_string, char *str, int size) +{ memcpy(parse_string->word, str, size); parse_string->length = size; } @@ -184,10 +182,10 @@ void set_ParseString(struct ParseString *parse_string, char *str, int size) { * 1 - if file does not have extension, * 2 - if file has no name * 3 - if file name or extension is too long -*/ + */ int split_filename_extension(struct ParseString *filename, - struct ParseString *name, - struct ParseString *extension) + struct ParseString *name, + struct ParseString *extension) { name->length = 0; extension->length = 0; @@ -198,10 +196,13 @@ int split_filename_extension(struct ParseString *filename, int words_count = get_words_count(temp_index); - if(words_count == 1) { + if (words_count == 1) + { // filename has no extension - if(temp_index[0].index == 0) { - if(temp_index[0].length > DIRECTORY_NAME_LENGTH) return 3; + if (temp_index[0].index == 0) + { + if (temp_index[0].length > DIRECTORY_NAME_LENGTH) + return 3; // copy name memcpy(name->word, filename->word, temp_index[0].length); name->length = temp_index[0].length; @@ -235,7 +236,8 @@ void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf struct IndexInfo param_indexes[INDEXES_MAX_COUNT]; reset_indexes(param_indexes, INDEXES_MAX_COUNT); - if ((uint32_t)indexes != 0) get_buffer_indexes(buf, param_indexes, '/', indexes->index, indexes->length); + if ((uint32_t)indexes != 0) + get_buffer_indexes(buf, param_indexes, '/', indexes->index, indexes->length); int i = 0; @@ -403,6 +405,21 @@ void ls_command(struct CurrentDirectoryInfo info) } } +/** + * Parse raw path to become useable for cd command + * + * @param indexes initial IndexInfo struct that contains the raw path at index 1 + * @param new_path_indexes new path after parsing + * + * @return - + */ +void parse_path_for_cd(struct IndexInfo *indexes, struct IndexInfo *new_path_indexes) +{ + reset_indexes(new_path_indexes, INDEXES_MAX_COUNT); + // [path_segment_1] [path_segment_2] [path_segment_3] ... + get_buffer_indexes(buf, new_path_indexes, '/', indexes[1].index, indexes[1].length); +} + /** * Handling mkdir command in shell * @@ -423,9 +440,7 @@ void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory } struct IndexInfo new_path_indexes[INDEXES_MAX_COUNT]; - reset_indexes(new_path_indexes, INDEXES_MAX_COUNT); - // [path_segment_1] [path_segment_2] [path_segment_3] ... - get_buffer_indexes(buf, new_path_indexes, '/', indexes[1].index, indexes[1].length); + path_to_cd(indexes, &new_path_indexes); int i = 0; int target_buf_length = 6; // "cd " @@ -450,12 +465,9 @@ void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory } // temporary CurrentDirectoryInfo for creating the new directory - struct CurrentDirectoryInfo target_directory = { - .current_cluster_number = info->current_cluster_number, - .current_path_count = info->current_path_count, - }; + struct CurrentDirectoryInfo target_directory = {}; - memcpy(target_directory.paths, info->paths, sizeof(info->paths)); + copy_directory_info(&target_directory, info); // check if path_segment count > 1 if (!is_default_index(new_path_indexes[1])) @@ -509,9 +521,7 @@ void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryIn buf[2] = ' '; // t struct IndexInfo new_path_indexes[INDEXES_MAX_COUNT]; - reset_indexes(new_path_indexes, INDEXES_MAX_COUNT); - // [path_segment_1] [path_segment_2] [path_segment_3] ... - get_buffer_indexes(buf, new_path_indexes, '/', indexes[1].index, indexes[1].length); + path_to_cd(indexes, &new_path_indexes); int i = 0; int target_buf_length = 4; // "cd " @@ -555,10 +565,10 @@ void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryIn .buffer_size = CLUSTER_SIZE * 5, }; - struct ParseString target_filename; + struct ParseString target_filename = {}; set_ParseString(&target_filename, target_file_name, target_file_name_length); - struct ParseString target_file_name_parsed; - struct ParseString target_file_name_extension; + struct ParseString target_file_name_parsed = {}; + struct ParseString target_file_name_extension = {}; int split_result = split_filename_extension(&target_filename, &target_file_name_parsed, &target_file_name_extension); memcpy(read_request.name, target_file_name, sizeof(target_file_name)); @@ -599,7 +609,7 @@ uint32_t traverse_directories(char *target_name, uint32_t parent_cluster_number) struct ClusterBuffer cl[10]; struct FAT32DriverRequest read_folder_request = { .buf = &cl, - .ext = "\0\0\0", + .ext = EMPTY_EXTENSION, .parent_cluster_number = parent_cluster_number, .buffer_size = CLUSTER_SIZE * 10, }; @@ -654,7 +664,7 @@ void print_path(uint32_t cluster_number) struct ClusterBuffer cl[5]; struct FAT32DriverRequest read_folder_request = { .buf = &cl, - .ext = "\0\0\0", + .ext = EMPTY_EXTENSION, .parent_cluster_number = cluster_number, .buffer_size = CLUSTER_SIZE * 5, }; @@ -676,7 +686,8 @@ void print_path(uint32_t cluster_number) void cp_command(struct CurrentDirectoryInfo source_dir, struct ParseString *source_name, struct CurrentDirectoryInfo dest_dir, - struct ParseString *dest_name) { + struct ParseString *dest_name) +{ // prepare buffer in memory for copying struct ClusterBuffer cl[MAX_FILE_BUFFER_CLUSTER_SIZE]; @@ -685,12 +696,13 @@ void cp_command(struct CurrentDirectoryInfo source_dir, struct ParseString name; struct ParseString ext; int splitcode; - + // split source filename to name and extension splitcode = split_filename_extension(source_name, &name, &ext); - if(splitcode == 2 || splitcode == 3){ + if (splitcode == 2 || splitcode == 3) + { char msg[] = "Source file not found!\n"; - syscall(5, (uint32_t) msg, 19, 0xF); + syscall(5, (uint32_t)msg, 19, 0xF); return; } @@ -708,7 +720,7 @@ void cp_command(struct CurrentDirectoryInfo source_dir, // copy file to buffer memory int32_t retcode; syscall(0, (uint32_t)&read_request, (uint32_t)&retcode, 0); - + if (retcode == 0) { // read file to buffer success @@ -716,9 +728,10 @@ void cp_command(struct CurrentDirectoryInfo source_dir, // split source filename to name and extension splitcode = split_filename_extension(dest_name, &name, &ext); - if(splitcode == 2 || splitcode == 3){ + if (splitcode == 2 || splitcode == 3) + { char msg[] = "Source file not found!\n"; - syscall(5, (uint32_t) msg, 19, 0xF); + syscall(5, (uint32_t)msg, 19, 0xF); return; } @@ -735,8 +748,8 @@ void cp_command(struct CurrentDirectoryInfo source_dir, // copy file from memory to disk syscall(2, (uint32_t)&write_request, (uint32_t)&retcode, 0); - if(retcode ) { - + if (retcode) + { } } else @@ -745,16 +758,18 @@ void cp_command(struct CurrentDirectoryInfo source_dir, } } -void rm_command(struct CurrentDirectoryInfo file_dir, struct ParseString *file_name) { +void rm_command(struct CurrentDirectoryInfo file_dir, struct ParseString *file_name) +{ struct ParseString name; struct ParseString ext; int splitcode; - + // split source filename to name and extension splitcode = split_filename_extension(file_name, &name, &ext); - if(splitcode == 2 || splitcode == 3){ + if (splitcode == 2 || splitcode == 3) + { char msg[] = "Source file not found!\n"; - syscall(5, (uint32_t) msg, 19, 0xF); + syscall(5, (uint32_t)msg, 19, 0xF); return; } @@ -774,16 +789,16 @@ void rm_command(struct CurrentDirectoryInfo file_dir, struct ParseString *file_n void mv_command(struct CurrentDirectoryInfo source_dir, struct ParseString *source_name, struct CurrentDirectoryInfo dest_dir, - struct ParseString *dest_name) { + struct ParseString *dest_name) +{ cp_command(source_dir, - source_name, - dest_dir, - dest_name); - + source_name, + dest_dir, + dest_name); + rm_command(source_dir, source_name); } - int main(void) { const int DIRECTORY_DISPLAY_OFFSET = 23; From c4ed123660ae1a70ec353386abac5251213cccff Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Wed, 26 Apr 2023 13:35:17 +0700 Subject: [PATCH 013/101] feat: add syscall 1 --- src/interrupt.c | 9 +++++++-- src/user-shell.c | 6 +++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/interrupt.c b/src/interrupt.c index 175fa8a..f513eb4 100644 --- a/src/interrupt.c +++ b/src/interrupt.c @@ -129,6 +129,11 @@ void syscall(struct CPURegister cpu, __attribute__((unused)) struct InterruptSta struct FAT32DriverRequest request = *(struct FAT32DriverRequest*) cpu.ebx; *((int8_t*) cpu.ecx) = read(request); } + + else if (cpu.eax == 1) { + struct FAT32DriverRequest request = *(struct FAT32DriverRequest*) cpu.ebx; + *((int8_t*) cpu.ecx) = read_directory(request); + } else if (cpu.eax == 4) { keyboard_state_activate(); @@ -140,8 +145,8 @@ void syscall(struct CPURegister cpu, __attribute__((unused)) struct InterruptSta } else if (cpu.eax == 5) { - framebuffer_write_row(0, 0, "bruh", cpu.ecx, 0); - // puts((char *) cpu.ebx, cpu.ecx, cpu.edx); // belum diimplementasi + // framebuffer_write_row(0, 0, "bruh", cpu.ecx, 0); + puts((char *) cpu.ebx, cpu.ecx, cpu.edx); // belum diimplementasi } // read parent directory table only with its cluster number diff --git a/src/user-shell.c b/src/user-shell.c index fc488fe..e447b83 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -256,7 +256,7 @@ void ls_command(uint16_t current_cluster_number, struct CurrentDirectoryInfo inf int32_t retcode; - syscall(0, (uint32_t)&request, (uint32_t)&retcode, 0); + syscall(1, (uint32_t)&request, (uint32_t)&retcode, 0); if (retcode == 0) { @@ -339,7 +339,7 @@ void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory target_buff[i] = buf[i]; } // call cd command to move the directory - cd_command(target_buff, new_indexes, &target_directory); + cd_command(target_buff, new_indexes, &target_directory); } // create new directory in the target_directory @@ -377,7 +377,7 @@ int main(void) .current_cluster_number = ROOT_CLUSTER_NUMBER, .current_path_count = 0, }; - + // fungsi atas-atas belum fix :D while (TRUE) From 538164fbe47b21200f83db852409608226c8c1e8 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Wed, 26 Apr 2023 13:47:35 +0700 Subject: [PATCH 014/101] fix: change syscall number --- src/user-shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/user-shell.c b/src/user-shell.c index e447b83..bef897e 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -208,7 +208,7 @@ void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf int32_t retcode; - syscall(0, (uint32_t)&request, (uint32_t)&retcode, 0); + syscall(1, (uint32_t)&request, (uint32_t)&retcode, 0); dir_table = request.buf; uint32_t j = 0; From a5b5b09cf36a02f0d5eaf159edbd7bb123c8e6e2 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Wed, 26 Apr 2023 14:21:17 +0700 Subject: [PATCH 015/101] feat: add shell main flow --- src/user-shell.c | 96 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 89 insertions(+), 7 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index bef897e..1dc7178 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -70,6 +70,12 @@ void reset_indexes(struct IndexInfo *indexes) } } +void reset_buffer(char* buf, int length) +{ + for (int i = 0; i < length; i++) buf[i] = '\0'; +} + + void get_buffer_indexes(char *buf, struct IndexInfo *indexes, char delimiter, int starting_index, int buffer_length) { @@ -242,7 +248,7 @@ void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf } } -void ls_command(uint16_t current_cluster_number, struct CurrentDirectoryInfo info) +void ls_command(struct CurrentDirectoryInfo info) { struct ClusterBuffer cl[5]; struct FAT32DriverRequest request = { @@ -252,7 +258,7 @@ void ls_command(uint16_t current_cluster_number, struct CurrentDirectoryInfo inf .buffer_size = CLUSTER_SIZE * 5, }; - memcpy(request.name, info.paths[current_cluster_number - 1], DIRECTORY_NAME_LENGTH); + memcpy(request.name, info.paths[info.current_path_count - 1], DIRECTORY_NAME_LENGTH); int32_t retcode; @@ -270,7 +276,7 @@ void ls_command(uint16_t current_cluster_number, struct CurrentDirectoryInfo inf int j = 1; while (j < dirTable[i].table->n_of_entries) { - // TODO : output nama file/dir + syscall(5, (uint32_t)dirTable[i].table[j].name, DIRECTORY_NAME_LENGTH, 0xF); j++; } @@ -368,7 +374,7 @@ void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory int main(void) { - + const int DIRECTORY_DISPLAY_OFFSET = 23; char buf[SHELL_BUFFER_SIZE]; struct IndexInfo word_indexes[INDEXES_MAX_COUNT]; @@ -377,18 +383,94 @@ int main(void) .current_cluster_number = ROOT_CLUSTER_NUMBER, .current_path_count = 0, }; + // fungsi atas-atas belum fix :D while (TRUE) { - + reset_buffer(buf, SHELL_BUFFER_SIZE); reset_indexes(word_indexes); - if (current_directory_info.current_cluster_number) + + const int DIRECTORY_DISPLAY_LENGTH = DIRECTORY_DISPLAY_OFFSET + current_directory_info.current_path_count * DIRECTORY_NAME_LENGTH + 1; + + char directoryDisplay [DIRECTORY_DISPLAY_LENGTH]; + + memcpy(directoryDisplay, "forking-thread-IF2230:", DIRECTORY_DISPLAY_OFFSET); + + for (int i = 0; i < current_directory_info.current_path_count; i++) { + memcpy(directoryDisplay + (i * DIRECTORY_NAME_LENGTH) + DIRECTORY_DISPLAY_OFFSET, current_directory_info.paths[i], DIRECTORY_NAME_LENGTH); } + + memcpy(directoryDisplay + DIRECTORY_DISPLAY_LENGTH-1, "$", 1); + + syscall(5, (uint32_t)directoryDisplay, DIRECTORY_DISPLAY_LENGTH, 0xF); + syscall(4, (uint32_t)buf, SHELL_BUFFER_SIZE, 0); - syscall(5, (uint32_t)buf, SHELL_BUFFER_SIZE, 0xF); // syscall ini belum implement fungsi put + syscall(5, (uint32_t)buf, SHELL_BUFFER_SIZE, 0xF); + + get_buffer_indexes(buf, word_indexes, ' ', 0, SHELL_BUFFER_SIZE); + + int commandNumber = get_command_number(buf, word_indexes[0].index, word_indexes[0].length); + + if (commandNumber == -1) + { + syscall(5, "Command not found!\n", 19, 0xF); + } + + else + { + if (commandNumber == 0) + { + cd_command(buf, word_indexes, ¤t_directory_info); + } + + if (commandNumber == 1) + { + ls_command(current_directory_info); + } + + if (commandNumber == 2) + { + + } + + if (commandNumber == 3) + { + + } + + if (commandNumber == 4) + { + + } + + if (commandNumber == 5) + { + + } + + if (commandNumber == 6) + { + + } + + if (commandNumber == 7) + { + + } + + if (commandNumber == 8) + { + + } + } + + if (current_directory_info.current_cluster_number) + { + + } } return 0; From 84b2a570a33a86331e746514801b7a2afe4c5051 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Wed, 26 Apr 2023 15:55:14 +0700 Subject: [PATCH 016/101] refactor: change cd command parameter --- src/fat32.c | 26 +++++++++++++------------- src/interrupt.c | 13 ++++++++++++- src/user-shell.c | 21 +++++++++++---------- 3 files changed, 36 insertions(+), 24 deletions(-) diff --git a/src/fat32.c b/src/fat32.c index 23904d9..5922c92 100644 --- a/src/fat32.c +++ b/src/fat32.c @@ -628,20 +628,20 @@ bool is_subdirectory_immediately_empty(struct FAT32DirectoryEntry *entry) { return !found_filled; } -bool is_subdirectory_recursively_empty(struct FAT32DirectoryEntry *entry) { - struct FAT32DirectoryTable subdir_table; - read_clusters(&subdir_table, entry->cluster_low, 1); - for (uint8_t j = 1; j < CLUSTER_SIZE / sizeof(struct FAT32DirectoryEntry); - j++) { - struct FAT32DirectoryEntry *sub_entry = &(subdir_table.table[j]); - // Check if the entry not empty - if (!is_entry_empty(sub_entry)) { - return FALSE; - } - } +// bool is_subdirectory_recursively_empty(struct FAT32DirectoryEntry *entry) { +// struct FAT32DirectoryTable subdir_table; +// read_clusters(&subdir_table, entry->cluster_low, 1); +// for (uint8_t j = 1; j < CLUSTER_SIZE / sizeof(struct FAT32DirectoryEntry); +// j++) { +// struct FAT32DirectoryEntry *sub_entry = &(subdir_table.table[j]); +// // Check if the entry not empty +// if (!is_entry_empty(sub_entry)) { +// return FALSE; +// } +// } - return TRUE; -}; +// return TRUE; +// }; void reset_cluster(uint32_t cluster_number) { write_clusters(empty_cluster_value, cluster_number, 1); diff --git a/src/interrupt.c b/src/interrupt.c index f513eb4..082bd21 100644 --- a/src/interrupt.c +++ b/src/interrupt.c @@ -152,6 +152,17 @@ void syscall(struct CPURegister cpu, __attribute__((unused)) struct InterruptSta // read parent directory table only with its cluster number else if (cpu.eax == 6) { struct FAT32DriverRequest request = *(struct FAT32DriverRequest*) cpu.ebx; - read_clusters(request.buf, request.parent_cluster_number, 1); + + if (request.buffer_size >= CLUSTER_SIZE) + { + read_clusters(request.buf, request.parent_cluster_number, 1); + *((int8_t*) cpu.ecx) = 0; + } + + else + { + // buffer size too small + *((int8_t*) cpu.ecx) = 1; + } } } diff --git a/src/user-shell.c b/src/user-shell.c index 1dc7178..439cb87 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -9,6 +9,7 @@ #define DIRECTORY_NAME_LENGTH 8 #define INDEXES_MAX_COUNT SHELL_BUFFER_SIZE #define PATH_MAX_COUNT 256 + const char command_list[COMMAND_COUNT][COMMAND_MAX_SIZE] = { "cd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "ls\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", @@ -141,12 +142,6 @@ int get_words_count(struct IndexInfo *indexes) void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInfo *info) { - if (get_words_count(indexes) != 2) - { - // tulis parameter cd tidak valid - return; - } - struct IndexInfo param_indexes[INDEXES_MAX_COUNT]; reset_indexes(param_indexes); @@ -154,13 +149,13 @@ void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf int i = 0; - if (buf[indexes[1].index] == '/') + if (buf[indexes[1].index] == '/' || buf[indexes[1].index] == '.') { info->current_cluster_number = ROOT_CLUSTER_NUMBER; info->current_path_count = 0; } - while (i < INDEXES_MAX_COUNT && !is_default_index(param_indexes[i])) + while ((uint32_t) indexes != 0 && i < INDEXES_MAX_COUNT && !is_default_index(param_indexes[i])) { if (param_indexes[i].length == 1 && buf[param_indexes[i].index] == '.') @@ -345,7 +340,7 @@ void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory target_buff[i] = buf[i]; } // call cd command to move the directory - cd_command(target_buff, new_indexes, &target_directory); + cd_command(target_buff, new_indexes+1, &target_directory); } // create new directory in the target_directory @@ -378,6 +373,8 @@ int main(void) char buf[SHELL_BUFFER_SIZE]; struct IndexInfo word_indexes[INDEXES_MAX_COUNT]; + char too_many_args_msg[] = "Too many arguments\n"; + struct CurrentDirectoryInfo current_directory_info = { .current_cluster_number = ROOT_CLUSTER_NUMBER, @@ -421,9 +418,13 @@ int main(void) else { + int argsCount = get_words_count(word_indexes); + if (commandNumber == 0) { - cd_command(buf, word_indexes, ¤t_directory_info); + if (argsCount == 1) cd_command(buf, (uint32_t) 0, ¤t_directory_info); + else if (argsCount == 2) cd_command(buf, word_indexes + 1, ¤t_directory_info); + else syscall(5, too_many_args_msg, 20, 0xF); } if (commandNumber == 1) From 179472bf2a5a7897b7dbb0168808ef0543fc806a Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Wed, 26 Apr 2023 16:00:47 +0700 Subject: [PATCH 017/101] fix: change path condition --- src/user-shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/user-shell.c b/src/user-shell.c index 439cb87..9c85a76 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -149,7 +149,7 @@ void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf int i = 0; - if (buf[indexes[1].index] == '/' || buf[indexes[1].index] == '.') + if (buf[indexes[1].index] == '/') { info->current_cluster_number = ROOT_CLUSTER_NUMBER; info->current_path_count = 0; From a251e7184cdfee6584b86c9d84d09b67abb76ac9 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Wed, 26 Apr 2023 16:53:10 +0700 Subject: [PATCH 018/101] feat: add edge cases for cd command --- src/user-shell.c | 67 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 55 insertions(+), 12 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index 9c85a76..88e788e 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -63,6 +63,11 @@ void syscall(uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx) __asm__ volatile("int $0x30"); } +void print_newline() +{ + syscall(5, "\n", 1, 0xF); +} + void reset_indexes(struct IndexInfo *indexes) { for (int i = 0; i < INDEXES_MAX_COUNT; i++) @@ -140,16 +145,28 @@ int get_words_count(struct IndexInfo *indexes) return count; } +void copy_directory_info(struct CurrentDirectoryInfo *dest, struct CurrentDirectoryInfo *source) +{ + dest->current_cluster_number = source->current_cluster_number; + dest->current_path_count = source->current_path_count, + memcpy(dest->paths, source->paths, PATH_MAX_COUNT); +} + + void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInfo *info) { + + struct CurrentDirectoryInfo temp_info = {}; + copy_directory_info(&temp_info, info); + struct IndexInfo param_indexes[INDEXES_MAX_COUNT]; reset_indexes(param_indexes); - get_buffer_indexes(buf, param_indexes, '/', indexes[1].index, indexes[1].length); + get_buffer_indexes(buf, param_indexes, '/', indexes->index, indexes->length); int i = 0; - if (buf[indexes[1].index] == '/') + if (buf[indexes->index] == '/') { info->current_cluster_number = ROOT_CLUSTER_NUMBER; info->current_path_count = 0; @@ -168,35 +185,43 @@ void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf { // TODO :go to parent dir - if (info->current_cluster_number != ROOT_CLUSTER_NUMBER) + if (temp_info.current_cluster_number != ROOT_CLUSTER_NUMBER) { struct ClusterBuffer cl = {0}; struct FAT32DriverRequest request = { .buf = &cl, .name = "\0\0\0\0\0\0\0\0", .ext = "\0\0\0", - .parent_cluster_number = info->current_cluster_number, - .buffer_size = CLUSTER_SIZE * 5, + .parent_cluster_number = temp_info.current_cluster_number, + .buffer_size = CLUSTER_SIZE, }; syscall(6, (uint32_t)&request, 0, 0); struct FAT32DirectoryTable *dir_table = request.buf; - info->current_cluster_number = dir_table->table->cluster_low; - info->current_path_count--; + temp_info.current_cluster_number = dir_table->table->cluster_low; + temp_info.current_path_count--; } } else { + if (param_indexes[i].length > DIRECTORY_NAME_LENGTH) + { + syscall(5, "Directory name is too long: ", 29, 0xF); + syscall(5, buf + param_indexes[i].index, param_indexes[i].length, 0xF); + print_newline(); + + return; + } struct ClusterBuffer cl[5]; struct FAT32DriverRequest request = { .buf = &cl, .name = "\0\0\0\0\0\0\0\0", .ext = "\0\0\0", - .parent_cluster_number = info->current_cluster_number, + .parent_cluster_number = temp_info.current_cluster_number, .buffer_size = CLUSTER_SIZE * 5, }; @@ -204,13 +229,24 @@ void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf struct FAT32DirectoryTable *dir_table = request.buf; - memcpy(request.name, info->paths[info->current_path_count - 1], DIRECTORY_NAME_LENGTH); + memcpy(request.name, temp_info.paths[temp_info.current_path_count - 1], DIRECTORY_NAME_LENGTH); request.parent_cluster_number = dir_table->table->cluster_low; int32_t retcode; syscall(1, (uint32_t)&request, (uint32_t)&retcode, 0); + if (retcode != 0) + { + syscall(5, "Failed to read directory: ", 27, 0xF); + syscall(5, request.name, DIRECTORY_NAME_LENGTH, 0xF); + print_newline(); + + if (retcode == 1) syscall(5, "Error: not a folder\n", 21, 0xF); + else if (retcode == 2) syscall(5, "Error: directory not found\n", 21, 0xF); + return; + } + dir_table = request.buf; uint32_t j = 0; bool found = FALSE; @@ -226,9 +262,9 @@ void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf if (memcmp(entry->name, buf + param_indexes[i].index, param_indexes[i].length) == 0 && entry->attribute == ATTR_SUBDIRECTORY) { - info->current_cluster_number = entry->cluster_low; - memcpy(info->paths[info->current_path_count], request.name, DIRECTORY_NAME_LENGTH); - info->current_path_count++; + temp_info.current_cluster_number = entry->cluster_low; + memcpy(temp_info.paths[temp_info.current_path_count], request.name, DIRECTORY_NAME_LENGTH); + temp_info.current_path_count++; found = TRUE; } @@ -241,6 +277,8 @@ void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf i++; } + + copy_directory_info(info, &temp_info); } void ls_command(struct CurrentDirectoryInfo info) @@ -367,6 +405,11 @@ void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory } } +void recursive_rm_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInfo *info) +{ + +} + int main(void) { const int DIRECTORY_DISPLAY_OFFSET = 23; From 8bb731253ca812c34ad1f31118c387f0a9ff1d7f Mon Sep 17 00:00:00 2001 From: Genvictus Date: Wed, 26 Apr 2023 17:23:38 +0700 Subject: [PATCH 019/101] feat: filename name & extension split --- src/user-shell.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/user-shell.c b/src/user-shell.c index 1dc7178..ada3cda 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -139,6 +139,44 @@ int get_words_count(struct IndexInfo *indexes) return count; } +/** + * Split filename into name and extension + * @param filename original filename before split + * @param filename_length length of filename + * @param name final filename length after removed of extension + * @param extension extension of the file + * @return + * 0 - if successfully split with filename not empty and extension not empty, + * 1 - if file does not have extension, + * 2 - if file has no name + * 3 - if file name or extension is too long +*/ +int split_filename_extension(char *filename, int filename_length, char *name, char *extension) +{ + // parse filename to name and extension + struct IndexInfo temp_index[INDEXES_MAX_COUNT]; + get_buffer_indexes(filename, temp_index, '.', 0, filename_length); + + int words_count = get_words_count(temp_index); + + if(words_count == 1) { + if(temp_index[0].index == 0) return 1; // filename has no extension + if(temp_index[0].index > 0) return 2; // file has no name (why?) + } + + int last_word_starting_index = temp_index[words_count-1].index; + int last_word_length = temp_index[words_count-1].length + // starting from 0 to (last_word_starting_index - 2) is file name + int name_length = last_word_starting_index - 1; // therefore (last_word_starting_index - 2) + 1 is length of name + + if(name_length > DIRECTORY_NAME_LENGTH || last_word_length > 3) return 3 + // copy name + memcpy(name, filename, name_length); + // copy extension + memcpy(extension, &filename[last_word_starting_index], last_word_length); + return 0; +} + void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInfo *info) { if (get_words_count(indexes) != 2) From e28493f5757919c9b6d4c0783462ddcc71d16770 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Wed, 26 Apr 2023 17:35:53 +0700 Subject: [PATCH 020/101] fix: directory search condition --- src/fat32.c | 24 ++++-------------------- src/user-shell.c | 11 ++++------- 2 files changed, 8 insertions(+), 27 deletions(-) diff --git a/src/fat32.c b/src/fat32.c index 5922c92..bf55714 100644 --- a/src/fat32.c +++ b/src/fat32.c @@ -458,23 +458,15 @@ int8_t delete(struct FAT32DriverRequest request) { uint16_t now_cluster_number = request.parent_cluster_number; uint16_t prev_cluster_number; - bool is_deleting_directory = memcmp(request.ext, "\0\0\0", 3) == 0; + while (!end_of_directory && !found_directory) { for (uint8_t i = 1; i < CLUSTER_SIZE / sizeof(struct FAT32DirectoryEntry) && !found_directory; i++) { entry = &(driver_state.dir_table_buf.table[i]); if (!is_entry_empty(entry)) { - if (is_deleting_directory) { - found_directory = - is_subdirectory(entry) && is_dir_name_same(entry, request); - } - - else { - found_directory = - !is_subdirectory(entry) && is_dir_ext_name_same(entry, request); + found_directory = is_dir_ext_name_same(entry, request); } - } else { found_directory = FALSE; @@ -813,16 +805,8 @@ bool is_requested_directory_already_exist(struct FAT32DriverRequest req) { // Check if it's similar - if (is_creating_directory) - { - same_entry = is_dir_name_same(entry, req); - } - else - { - same_entry = - is_dir_ext_name_same(entry, req); - } - + same_entry = is_dir_ext_name_same(entry, req); + if (same_entry) { return TRUE; } diff --git a/src/user-shell.c b/src/user-shell.c index 88e788e..990696c 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -149,7 +149,7 @@ void copy_directory_info(struct CurrentDirectoryInfo *dest, struct CurrentDirect { dest->current_cluster_number = source->current_cluster_number; dest->current_path_count = source->current_path_count, - memcpy(dest->paths, source->paths, PATH_MAX_COUNT); + memcpy(dest->paths, source->paths, PATH_MAX_COUNT * DIRECTORY_NAME_LENGTH); } @@ -362,12 +362,9 @@ void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory } // temporary CurrentDirectoryInfo for creating the new directory - struct CurrentDirectoryInfo target_directory = { - .current_cluster_number = info->current_cluster_number, - .current_path_count = info->current_path_count, - }; + struct CurrentDirectoryInfo target_directory = {}; - memcpy(target_directory.paths, info->paths, sizeof(info->paths)); + copy_directory_info(&target_directory, info); // check if path_segment count > 1 if (!is_default_index(new_path_indexes[1])) @@ -407,7 +404,7 @@ void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory void recursive_rm_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInfo *info) { - + } int main(void) From 59aa8ebcc26eb1c96d9d9b8b3c12cd1a047dd428 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Wed, 26 Apr 2023 17:56:01 +0700 Subject: [PATCH 021/101] fix: warning and error --- src/user-shell.c | 45 ++++++++++++++++++++++++++++----------------- user-entry.o | Bin 0 -> 1408 bytes 2 files changed, 28 insertions(+), 17 deletions(-) create mode 100644 user-entry.o diff --git a/src/user-shell.c b/src/user-shell.c index 5981ede..c2137ef 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -65,7 +65,8 @@ void syscall(uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx) void print_newline() { - syscall(5, "\n", 1, 0xF); + char newl[1] = "\n"; + syscall(5, (uint32_t) newl, 1, 0xF); } void reset_indexes(struct IndexInfo *indexes) @@ -178,11 +179,11 @@ int split_filename_extension(char *filename, int filename_length, char *name, ch } int last_word_starting_index = temp_index[words_count-1].index; - int last_word_length = temp_index[words_count-1].length + int last_word_length = temp_index[words_count-1].length; // starting from 0 to (last_word_starting_index - 2) is file name int name_length = last_word_starting_index - 1; // therefore (last_word_starting_index - 2) + 1 is length of name - if(name_length > DIRECTORY_NAME_LENGTH || last_word_length > 3) return 3 + if(name_length > DIRECTORY_NAME_LENGTH || last_word_length > 3) return 3; // copy name memcpy(name, filename, name_length); // copy extension @@ -246,8 +247,9 @@ void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf { if (param_indexes[i].length > DIRECTORY_NAME_LENGTH) { - syscall(5, "Directory name is too long: ", 29, 0xF); - syscall(5, buf + param_indexes[i].index, param_indexes[i].length, 0xF); + char msg[] = "Directory name is too long: "; + syscall(5, (uint32_t) msg, 29, 0xF); + syscall(5,(uint32_t) buf + param_indexes[i].index, param_indexes[i].length, 0xF); print_newline(); return; @@ -274,15 +276,24 @@ void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf syscall(1, (uint32_t)&request, (uint32_t)&retcode, 0); if (retcode != 0) - { - syscall(5, "Failed to read directory: ", 27, 0xF); - syscall(5, request.name, DIRECTORY_NAME_LENGTH, 0xF); + { + char msg[] = "Failed to read directory: "; + syscall(5, (uint32_t) msg, 27, 0xF); + syscall(5, (uint32_t) request.name, DIRECTORY_NAME_LENGTH, 0xF); print_newline(); if (retcode == 1) - syscall(5, "Error: not a folder\n", 21, 0xF); + { + char errorMsg[] = "Error: not a folder\n"; + syscall(5, (uint32_t)errorMsg, 21, 0xF); + } + else if (retcode == 2) - syscall(5, "Error: directory not found\n", 21, 0xF); + { + char errorMsg[] = "Error: directory not found\n"; + syscall(5, (uint32_t) errorMsg, 21, 0xF); + } + return; } @@ -391,7 +402,9 @@ void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory if (new_path_indexes[i].length > 8) { - syscall(5, (uint32_t) "Invalid new directory name! Maximum 7 characters!", SHELL_BUFFER_SIZE, 0xF); + char msg[] = "Invalid new directory name! Maximum 7 characters!"; + + syscall(5, (uint32_t) msg, SHELL_BUFFER_SIZE, 0xF); return; } @@ -608,9 +621,6 @@ void print_path(uint32_t cluster_number) } } -void recursive_rm_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInfo *info) -{ -} int main(void) { @@ -639,7 +649,7 @@ int main(void) memcpy(directoryDisplay, "forking-thread-IF2230:", DIRECTORY_DISPLAY_OFFSET); - for (int i = 0; i < current_directory_info.current_path_count; i++) + for (uint32_t i = 0; i < current_directory_info.current_path_count; i++) { memcpy(directoryDisplay + (i * DIRECTORY_NAME_LENGTH) + DIRECTORY_DISPLAY_OFFSET, current_directory_info.paths[i], DIRECTORY_NAME_LENGTH); } @@ -657,7 +667,8 @@ int main(void) if (commandNumber == -1) { - syscall(5, "Command not found!\n", 19, 0xF); + char msg[] = "Command not found!\n"; + syscall(5, (uint32_t) msg, 19, 0xF); } else @@ -671,7 +682,7 @@ int main(void) else if (argsCount == 2) cd_command(buf, word_indexes + 1, ¤t_directory_info); else - syscall(5, too_many_args_msg, 20, 0xF); + syscall(5, (uint32_t) too_many_args_msg, 20, 0xF); } if (commandNumber == 1) diff --git a/user-entry.o b/user-entry.o new file mode 100644 index 0000000000000000000000000000000000000000..edf2aadd2e5bc828ba5b263eb2f44167a7d10b37 GIT binary patch literal 1408 zcmb7EJ#W-N5S{fU;gCq=goq%4P#Oe6!jOm*d$Ds3AQgH6%l`c zo{EB!k{abFz}&%5JWCk0|ov%B-=?aZ@xeQzH=S~13mnvsr-B9UdExKYoS zC6-f4{jZrd=@Wj}K_qe_s1W-#v9SLkc=G{Ib7z2!1^5r}&LWpjIwy8uj0`+fm%QbEi+;PE;6yyUPR<8Qx*!{PToSUEe7$>|`&S$NN=#drbK zV?xo0@5255T8i#1i?wTm(iT^3UKM*uDNpV{dpy6GEG#A0m&EKJDT6A`>V94d&qw=( zy=RH@^1yDwmBZLf<2PgCiB9)o_cTaRBGYD>Wox^QF_KFdjrlb-iLw5eq20(a&GnA) zTI$@3C<0mdU5EW7sqC9dl2# zWrf{U>Q*neEvf??b-h5j!KNdY=f6$ Date: Wed, 26 Apr 2023 17:58:27 +0700 Subject: [PATCH 022/101] refactor: create ParseString struct --- .vscode/c_cpp_properties.json | 32 +++++------ .vscode/settings.json | 18 +++++- src/user-shell.c | 105 ++++++++++++++++++++++++++++++++-- 3 files changed, 133 insertions(+), 22 deletions(-) diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index fc7e79a..8bc661a 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -1,17 +1,17 @@ -{ - "configurations": [ - { - "name": "Linux", - "includePath": [ - "${workspaceFolder}/**" - ], - "defines": [], - "compilerPath": "/usr/bin/gcc", - "cStandard": "c17", - "cppStandard": "gnu++17", - "intelliSenseMode": "linux-gcc-x64", - "configurationProvider": "ms-vscode.cmake-tools" - } - ], - "version": 4 +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [], + "compilerPath": "C:/ProgramData/chocolatey/bin/gcc.exe", + "cStandard": "c17", + "cppStandard": "gnu++17", + "intelliSenseMode": "linux-gcc-x64", + "configurationProvider": "ms-vscode.cmake-tools" + } + ], + "version": 4 } \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 54291af..ece5484 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,8 +1,24 @@ { "debug.onTaskErrors": "debugAnyway", "files.associations": { + "*.pl": "prolog", "framebuffer.h": "c", - "*.h": "c" + "*.h": "c", + "array": "c", + "atomic": "c", + "*.tcc": "c", + "concepts": "c", + "type_traits": "c", + "istream": "c", + "new": "c", + "numeric": "c", + "ostream": "c", + "string_view": "c", + "system_error": "c", + "functional": "c", + "tuple": "c", + "typeinfo": "c", + "utility": "c" }, "C_Cpp.errorSquiggles": "enabled", } \ No newline at end of file diff --git a/src/user-shell.c b/src/user-shell.c index 3bf9849..db49f7a 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -10,6 +10,8 @@ #define INDEXES_MAX_COUNT SHELL_BUFFER_SIZE #define PATH_MAX_COUNT 256 +#define EMPTY_EXTENSION "\0\0\0" +#define EMPTY_NAME "\0\0\0\0\0\0\0\0" const char command_list[COMMAND_COUNT][COMMAND_MAX_SIZE] = { "cd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "ls\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", @@ -44,6 +46,11 @@ struct IndexInfo defaultIndexInfo = { .length = 0, }; +struct ParseString { + char *word; + int length; +} __attribute__((packed)); + void syscall(uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx) { __asm__ volatile("mov %0, %%ebx" @@ -164,7 +171,9 @@ void copy_directory_info(struct CurrentDirectoryInfo *dest, struct CurrentDirect * 2 - if file has no name * 3 - if file name or extension is too long */ -int split_filename_extension(char *filename, int filename_length, char *name, char *extension) +int split_filename_extension(char *filename, int filename_length, + struct ParseString *name, + struct ParseString *extension) { // parse filename to name and extension struct IndexInfo temp_index[INDEXES_MAX_COUNT]; @@ -178,15 +187,17 @@ int split_filename_extension(char *filename, int filename_length, char *name, ch } int last_word_starting_index = temp_index[words_count-1].index; - int last_word_length = temp_index[words_count-1].length + int last_word_length = temp_index[words_count-1].length; // starting from 0 to (last_word_starting_index - 2) is file name int name_length = last_word_starting_index - 1; // therefore (last_word_starting_index - 2) + 1 is length of name - if(name_length > DIRECTORY_NAME_LENGTH || last_word_length > 3) return 3 + if(name_length > DIRECTORY_NAME_LENGTH || last_word_length > 3) return 3; // copy name - memcpy(name, filename, name_length); + memcpy(name->word, filename, name_length); + name->length = name_length; // copy extension - memcpy(extension, &filename[last_word_starting_index], last_word_length); + memcpy(extension->word, &filename[last_word_starting_index], last_word_length); + extension->length = last_word_length; return 0; } @@ -611,6 +622,90 @@ void print_path(uint32_t cluster_number) } } +void cp_command(struct CurrentDirectoryInfo source_dir, + char *source_name, int source_name_length, + struct CurrentDirectoryInfo dest_dir, + char *dest_name, int dest_name_length) { + + // prepare buffer in memory for copying + struct ClusterBuffer cl[256]; + + /* COPYING STAGE */ + + // filename contains dot (".", but not extension delimiter) + if(get_words_count(temp_index) > 2) { + syscall(5, "File name error!\n", 19, 0xF); + return; + } + + // prepare read file request + struct FAT32DriverRequest read_request = { + .buf = &cl, + // .name, + .ext = EMPTY_EXTENSION, + .parent_cluster_number = source_dir.current_cluster_number, + .buffer_size = CLUSTER_SIZE * 256, + }; + memcpy(read_request.name, source_name, temp_index[0].length); + + // get destination extension + if(temp_index[1].length > 0){ + char *extension = &source_name[temp_index[1].index]; + memcpy(read_request.ext, extension, temp_index[1].length); + } + + // copy file to buffer memory + int32_t retcode; + + syscall(0, (uint32_t)&read_request, (uint32_t)&retcode, 0); + + if (retcode == 0) + { + // read file to buffer success + /* COPYING STAGE */ + // parse filename to name and extension + struct IndexInfo temp_index[2]; + get_buffer_indexes(dest_name, temp_index, '.', 0, dest_name_length); + + // get destination extension + extension = &dest_name[temp_index[1].index]; + + // prepare read file request + struct FAT32DriverRequest read_request = { + .buf = &cl, + // .name, + // .ext, + .parent_cluster_number = source_dir.current_cluster_number, + .buffer_size = CLUSTER_SIZE * 256, + }; + memcpy(read_request.name, source_name, temp_index[0].length); + memcpy(read_request.ext, extension, temp_index[1].length); + + // copy file to buffer memory + int32_t retcode; + + syscall(0, (uint32_t)&read_request, (uint32_t)&retcode, 0); + } + else + { + // try read folder + } +} + +void rm_command(struct CurrentDirectoryInfo current_dir, char *filename) { + struct FAT32DriverRequest delete_request = { + .ext = EMPTY_EXTENSION, + .parent_cluster_number = current_dir.current_cluster_number, + .buffer_size = CLUSTER_SIZE * 5, + }; +} + +void mv_command(struct CurrentDirectoryInfo currentDir, struct) { + cp_command(currentDir); + +} + + void recursive_rm_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInfo *info) { } From c7eaa658244c3b5a1cf10efd1b102d503f4f8a46 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Wed, 26 Apr 2023 18:13:19 +0700 Subject: [PATCH 023/101] fix: warning --- src/user-shell.c | 3 +-- user-shell.o | Bin 0 -> 21712 bytes 2 files changed, 1 insertion(+), 2 deletions(-) create mode 100644 user-shell.o diff --git a/src/user-shell.c b/src/user-shell.c index c2137ef..14c7739 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -193,7 +193,6 @@ int split_filename_extension(char *filename, int filename_length, char *name, ch void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInfo *info) { - struct CurrentDirectoryInfo temp_info = {}; copy_directory_info(&temp_info, info); @@ -500,7 +499,7 @@ void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryIn // check if path_segment count > 1 if (!is_default_index(new_path_indexes[1])) { - char *target_buff; + char target_buff[target_buf_length]; for (int i = 0; i < target_buf_length; i++) { target_buff[i] = buf[i]; diff --git a/user-shell.o b/user-shell.o new file mode 100644 index 0000000000000000000000000000000000000000..533e5c38c53dcffdfdf44f72d07eebb2b604af77 GIT binary patch literal 21712 zcmeHv3wTu3wf{cn%uY^{$vcE3AekWHX&wXxfgm6Z2qYL@5_yG?%;aHS&I81PJcbd+ zF_s``Z>4DKqgGL?tw8lw18RnHQK`kpzZd_cnzm4KYpznEUfTSBYoC246F}>~-@X6u z`+uK@Z)WZF*lVw~_S$RjbIycK_L5nOqA>GPn8x}r##S#dIM)g=lBKf&Y)RnvLAy2Z zdeEK}I25#}1r7)8dZ7KS!W}DL2hZ1?)M4+9ZMFB-C)O)v_5Ae3-rio{8%aBUCD|eS zMN)TmSkQj4HSJAmLqn@o{h??MumA*6Hrg)=;SA+?zMW ze~rg6=BT5AGN`;@xP5M8YJWTYMToi)vPHh`G~dP~+g;HILF+v`D`Y%Bw>uCxZ1=*n+>-IlTi3(a}+w|jZee(r3d&wftvZ9Eru*Aby7xbmWyQA~mF zLa#RgNdeL5gOopK`9V@>CWJZTku$ohoLur_cBHmi2mdDU>ED z615;r;H%=z4GKwk7ArhEvy}oRX^5yw-rkP*_)aUqZEup+fW0S-cMBXT*aLpRe%iP3 zw7x0Ix3OD8Uyb@+7X%dnhbg_@B-7*|(zdjRX5%O^7xsG7OqPhO2+Y!37H#QfNyuF5 zFm~nEF}U37?|>D*h(hxfjK~5Rfff42R%Fk|7e^ge4*7m}@z5DH@Im0i&!6#ilNCmf zaQuATR!}}gyi6M~AHgyUeKRl@mem(Xfxdv+LiR2iO$dn^p&ZBRDK1F#$8jPjIYXOi zMpbHuHq(^Rb>=^?{)6@|1oJ3{^j%QAIR;7=L@3Jl#`x@A%9&qYBCjU;d!XmCK8Rzz zTDuwP8Fs_pp6GuAvWW-mN1eV4YT~vAC~Mt4Ce+(|@KH$qLgZIQAS;N71y;mfY+YvY zeR6TsZxOd&%eWm4oCb1s3ujCYqQoQh+37W%W_vfD5ew`-!0aMB;&IST)$n?bf z9}+{agQl5vE=S1!9ki-E&90Dt6I$zSO_d?P53NRrtuEx>j+WczX%6{=Xf@j!(E2V~ zO*NBj9sUQBqoA{%43blGKob%i=`Dfc>};oYvix`iD9-ctKpf=Ews}a6kbecRS(SASA^&Q$9Mv{Y$X|_C zvyB2?i&kZ|tvcjyKnrtF74o;Bg*jLc4?Sp7Y}W$971D*+4vGj^*i_K<2)ZyQ=qFof zaV!e?XQOF%xiDw*&~i<(HHG{)qt)!OVU`!6Wpg&e%%x~mJ6y3H{^e+4RO$%r10uAa z*$>}L?N~}b7OswgpfN%LS{MOtjYG?DYXVy2R>(gYEn8DF0x^|Z&Sr1OKLf3%>R6g~ zv@RWPwir%MTFBl>snB6R#m*e1oUngL_!&y(puO`@XB?&3aoSNoJk-f)Gd~uQf=Ih? z3PMCDxnr331$|oq>i8TG6ZcPxD^Bv>K+V3@bZNGo3%Bf16r)H(5h-wI7)$#en_`MdBDy1!;4u8fn&^%qzmwrA>TM@9DfVu|!5)}_j3F8TDUi8A=c#x4I`}SN zhuBNX{C8o?n$xrvbz&=84RzJFkpFJ9njGuUx)-f#v47l;ma%{AM9bJe9z?6rkpsE! zqg7gY2X>OZMDsR+_9L_=*s5wn{wL9@bXB4NK8=>g;c}w@K8I!wiUJu>pIA$`9g$@y z0S7BgI8F87;F8mFHJ=`1?@rvGa?dV)0?zsDICCKiyM)J(R*p}^Bpz?|zl}BX%?>wT#U-{vyJ8uio43Utyv zQg>@vZ(vDh;P645(`aQV$6uq?%lNSK=WlDrP1Kg(u^z0gk4GJyc*2t;4|4YnyO;=( zv)zHiTR!eZbJPj5<$u=`pGzd)X^Yb7(=n89mB(GTGj};S_SNwTzC+(kC1+Pnr${PPY0FU{?N#8u2!|1w?1m2nwI55gnk0{73Ok zHA0kxRzFQ3B1!}GFAP5g#h{DApqgg2IxZ|Xs@p$an`Kv8n^>eO7GtZQ)`vNZU$y## zOuyA9?wPO%aY7WU?;KVi&AWoLy-`7o)kieB2rpTEC}ot)xEl~#Q}-BqkCDtDqKgmd zizR~#VB+``bLyTlK!`VMgdqkRc{Xa?5&XD~yWk02< zSlD!55G?HkW~3>t>eG|$J^j*D_=Gg=G##KceFeGlPo(L)=oS#2k*4n>G$KtYK|_8@ z;fOS)sX?03K>gG7=b#vLk*3TvE9fT<_OGm<=yiE*J3H{;qcMzK&e+kH;)`0h4P!s; z?d`j(oA`$JGhg?$9rp7mnr}V-Px;-2ZUNC5>p$Q>2{h#I#5XH5)};j*Z)orD>=DQq z^h-Bu;?QkWmN>_eT`1XoTNTaonN#>eX`=1=%un%UY*yWJ*FH_Vc9+<-sWgxY;oLpQdAa4|OKd*-@xCg!EGIB?dj>YbTjl$k0uK z9`Q^750B2%vh;22nz}A?^TzYcn~JXCQ(jNv*0ESthDdkJSBR((N!)KgZ=Ni^;$Sfh zCCj%_SG|J|K7YmRIP*S2*XsZ1gMVu3&!JmDbVl_F_`89I{5|*w4W3= z=O3c+ve^3ngsuP8zODa@|JJP^&jmWMddg~FK<@N!6qbSi2B)IdW=}aNFE9)TtflQ_9QDN;xgOM4rmp54HMELOu#^jcO1&nmTtPU z!kH3xVj`Or9FXzMuH*A30zH8*6A$RlK&%MymN$|}^5mIGf5YlVHsAud;#F0BMRJ(f z;0`yh*l4^BcL!JG7{sbd&)0Ant7`dLHgh$8J->17*YnraI$Vyrf8fN|tN0(~=I8&9 zs{dB`w-NX@0^dg9+X#Fcfo~)5|6v4X)ipTieG0uvX{u%g%-QU^t*)si&r|DiR95HB znN?IYu5c0?#!kgE#+gD7rr~IN^$a9$(SvWAU9}iGBx1$oLL?Sp_Bj zB$~+?^NFcOPsW?Ncsp*p(g&_4ilR4>_#+?>N~1Ghj)m7Xc~~m76IA|$5Q=({gw~@wO>Cl?}KKRu0tKvJeIlwFhFT zDdVzB#Kj`wvRlN(YWWqZdr(-FXnBi#d`KXv>}pFU_0{f&dJ3zsG){bHv(y|=vNnJf zZzU!t6IogznW8I$H-ls;1)>azr8XOM3k0&sccu?Ig)wb2(8Oze;p~GD5sG_dI0pP4 z6kQqiOVYC$lFINHalc@>6%=KJKrAflerO$?Lfs7m27d(E!O>**f8diin7%%vui;>@ zr1NNI5@*=p5Ud-?N$Ef+NfhGZOGsWtFA#561;0Fvu_cgE_QWAR%1|`jYT|kbsNU5o z<)%lCC6?wrwo##9XL!~0K?dHaS*GWoMex{ zQw{m~z(p0%yya0W_igl0+ZtffS~geN zK*&*JX}mSbjQzW?L5dwoMuU)D3GTIVTSZbRkmLmL~vgD{hb)^$lom7lWZTqkp*8ENp3k#uDR${o1O|(|ofxw+n zVyUibZO5Axib{`SWO3Wk3W}9x&gs$bZc-8;Xfb2;GY}|N@n)>{eRosL1iXhLCm$ed z>e-)^1d)kt)r`Lb7QG2m{u7IEgmkY5cvi83`wEGdfB z$B;L2vTX%&Qh}BY$|tdm?LkY~GYXG6M5Hz-S&@<2pp1=-)COf~WTfskBXxoz73>QQ zMe05itycaG=)-2Djv0~qkr}BD5vhZU%>E7pW;IOzg(9>6c^Rq0ip>6}5UD|NjE#WS zUq%bhx0sP?U@^zQqW7^UiA76&w~|2aS=zq1e-n$Tw;C}%PwaZO$LzV9@sZf~!!h2c zBuqpvt!;4>e;5oI<7dqnQyPluKvE(B#~OGEa2aV@{ZvWkD?h{&z8f(O%AQZb7Fjo6 z$)nl9nxjl9GyU&;ev|Sl=nG8$e+2?%$}-dcH?aEaFmv=cNTC|LT9K>28nduQG3p`m z)q**%GSSt1JNnRp1YXxDMvZH$1wK%NVTZS4h%9ta_Iw|5akOd<50t48O^fDmzRZMZ zS~G_i%S6y$f(38Ntbesxe+}pnxqx1+u-37+BBd!KjD9;RM3ISCMj0J% z5^+mW2Gn2}t?j-Fc%G-E8)c+ixdZ0pD=9{4TN?8;#vprA;J%ge=F4=7gx2=yDi#xs zY@uH&)q*0DDnm(sT5wOSirE1s1-29fWj`9(O4iGQ`PwSRKLd9)h=P-=WE~Zp$5vr~ zz74r>6fE^NR-_Ct)@~VJ2Pzq&>_$w+D`S6)4r<#>P>cklaYe$(BNGiJ@GOH*0|-3L zz^T8$2eG8XP?E6$dY_`vUP9wtKxNN5ESl&)!ojD8nREUN#N(+V!zfEM9cZ4KWAOCo zY;<~RiGf-5T=aWJPI+guegYHqoLMw=q!fEeVzqh+u>BIN)*nR2gA!YfJj58g>0~@x z*z^?HGz!h#6O3GA(O;6pG6S=)jAAhFBMb9DpDsFmM4c#I?;ByHE7R}AJl`)z@vz*x zNp5=-O?y1#Y@%BfszUUi(cC_g>LwN?%b?%HtR?Nwp-~~kDj+77#@ZofnBIi9Ye$%2 zDn{qElMPJghtY95I${;vB};h&)>|54a?2B-$AGWw`Pfu?OSY+$9Jpn?x!$@Uddp0z z;%ZxUG!1ymB4Y?^^gxoVF|Z_zv(j`FNyOMHi8Y8IR7k9aWe1?F>^qPcjStE{3Y_q( zEYmcB4wYp?rC)pt#BBIrgoV-*l%MQ;kZzicuW9%wd)7dW2>wmOW$^iQFvjD9j&u7u ziiNM-7&RCi$|Ysbc68N$2G?fBQd4bPXC&`KKt%GQ-Y0^s6i`CpZh<<*IV$g91;#0_ zjm0_E0LwL&w2Z!~VABl@@m8*7TEe6pWip=_Hz!riz=)ve{V1BE%t=*n z%(BFjaNOiLlD!@Y#^aP^B?X2=<*+%a1(b4J>Ju`gPd7&hQ(}x>q%qbM4-b#u@fyR2 z#jU16VM=_u7(_J;!QI#}78iFzoR)yII)@?H?-N;Ej)hvuuo>=XeMYC`D^oK~r*oo4 zWReThGB#wAL8-$<|Fl#^ONisb*BqS~0|X^5f|4$LhKB?D6vj=wRAELxCLfVGCpB`s z%n4$=tbRe7nn{5hB%+O}fzkxT8)ay)smwy|kgj53^;ITa%;TkF3^79*4sv#%e5A#9 z3T3urB{v~8PRkyYO_nAN#5q_77;9;$@EW#UjSyqPhYd#t=1P4cHTs4(^bL<>M*2P? zl3`B6otZMLvFvc6WXa2X+(78xv6XP}Xi?!$P5vt(o`6D_AY^M)5o_?d4Ifp>RulQ1 z#NAF`yNE_7BlSu8;tJzpFs(r0e9H3W%U5!xU@DKT;d~xf^qi?Y0Zk82VyZ0{d?;a)!&2Kyc}#oFvz)KxanJFD<$UZMZX*p_c@}|v zd;)-4&c_ni$E~G&2+?2W83sGa&xdsJ#AQ68;2-tPE9KXA@uYk{tcz!t^Mo6Cx_0|q zKA043<>`h#MN8f~mFsu#q#B;Emb{EF-% z_wq4&d3-(3)OYeECr{r7Jte97JTR_W#?zcUYZ)J)PE6%P^#^z+(49bMr6Sr7^7J;I z;^nC&e84h3a4ny)jE_CSmp{id_wpI}eC*3Sx147d^NjcT?d05CUPr*gr*eCjv#H(>$!N6|9J z-D+S?WB7mQAJ%Ic94h_qaY*LK=n|?PiawmjTmw+6#cahG&+_aN)Q4L#u{_LV+Qw6M z@_}9o-k@bX-ouA1q+W0c5r2$ z7F&*p9OW^!n6($k>a4KMB|G`GdwFR&pS+jH>VhDMJR<@ zjC!4d6v3oc{DHfje71)Nkyfe2w1vc|EorC?wdDJE$dp2n?%Ml&24N^Q1j_k*0{SF= zJs_5Z*yEhMcqKxtuhnnRz4}^yl{z#HX>@fOPpRecYEde`O5e?sP{Pt``G6XftXBZk z+%(Wid2%gmD}!w+UP&kob&Yi%)==s8RIF=uRadw@l`aonVpP;MRXgrrc)IUsa@RFC zv1*6g!(0xx!(*@zOf3ox7si;jHvFNad`>h1VAq_?>%0U6X^kYnxpj8@%$;i+qMFi2NGe??OzkjBcoCf4X^tZG>g(}kA~moXabcQ&(1kH=NF#_Msgs%qHZ zh+nEz!@tVv3YX({FF8xPJe6x29L(crY>@$(;dQwjO`e&iA9F~T7p7egvsx-WwQknf zTwUj^b5vJUS3)~nGu{tXHF(|ld3{A~T}>@p)7;#^Yw=R8H7QE|?*kIcK4L z#^Re7-dZtp&Z4rC>92I)`#u%#@K=G*8Uk>~&QkQRr7vW=NQOy}PQip@B6}P8&IKdHiplHEWT5 zvCPVTBf1=(s^)5>l#wMBG!PWg;xN5vXkN#J_x-17u}Czz2>R?b{i;G{B90=XXjL$= zSj`AsvS=gMBrOVIg(=&&CY_jhSca4|;*B^MR!9*s#~xSZTKr82hL#CZhZ!+Uch!Nj zP%akJV^eIsTxG`kH0-Wuc8Z}$giF&e_Vc{Ew6E05xzX$CdZT-N0Y-21C2`e`lhN{S94Rd*PZ8WT8CN46E(#RrqQno#kbb%O_kQDIbJs$?kiFEQ(tXH68?6l5HjXV*su)jQ!g4ZC!ZHX#(cHSW?B_CCyA?G zHZxK4wnQaGtKJPsQL6WjBu(|w+n0V9%ne@__Mg3B1daax6A0mWk`!@iOgz;LQ#A80 z_$5VSc;pmuX$+4=BQA|4;Gc1Ah9Sw&KS<(ucm-Tz&86Hf2+%$z2ier{~$FyTJn=7o2X>|T7#{3ZUwz|DLm{2Ab8eiHr~aPy-69r&2} zN&Hj5&3q*MPr%K5Bm6JG&DnpJ#4$SJ^wj@&6?tU6 z;>jZ7d?rrt^urw$sk$6c!E2{V3Ev_*Qucj>Rl(c8Gk_|7hOi3jO-;euBZBz##&Lpp z(|w8{o<6U_6Mv$wm+&k>6n^^g0O`v?Jtuj3AxN*Z-yj@%PfNTB%Z%*dSY8ARCA^*> zUIRQR@goE=&Sw&@j5g%gOSpv~OV=snSd0(MG`+t5ON&4NX|hJv@U{!u#PY{B!4>~@&6#9 z4P&Y(Fe3qpKY?)YOC-EN5Vl4`H`%=xkmQ~u9G^}Jqw#|rqT`K+pyv>To{17JkkCyK zK0ZJYzI`I;UlN2(!{9UdeY1p4g3z;vAiboa{6vnx6sBNq;T}^!M0WwR2qG7U5=3r{ zAPBi@C7dYXObHiAc#DKp64pw%MZ$X|Y?bhP6230sI})Cj@Glaow0(*@Z>D;I@slBlJq}I{BIIkkz1s9jD*D! zmJ-A`w@BO}p-0m1m5|=SQ~%c_{*lDHCHyZ5Gmx7kN57{eI6=at64pw%o*>5ECE*Vw z{aJ~BBJnd4r=LBLzH|w5CA?9>1rkh14-|Z_+KQRf?TC>Y!c>6I7Py8f*9W;ai4@#$BF)o#9xu{ zsDyu%@C$;FOGPddER=8xL5w?J;!7n?Ki?s_O%mQC>75duk@O1^k3!8NJ!ujSm9S94 zsS=h-xLm?I3Ga|_BSDONpTxf};ZG!dQSuK-{2dAZw}fXT|ANG$v0ss0Nd%!cPvVm$ zoFnP0CGL>;R*CPBaIb{>B3iuw<_sQ-XBNcs#3Z<25!LFlmos({lZTrJ^d z2_KcPUBWI2EvUoPkIt$DXG&Nt;Vud3zf&WAmxM`Z6Mn6PBrCKU_By{$q&kB(+`o8 zW@o@>3vm7o8__q`GVn~@BtD~vF&j1HW%B5Z6FKf1H)CATXk4P3<2Isg_Cb?XL7y5C zK$BMoUZlPg&__0tK9rlVKKd~@^`SV@<(Oog>kZ7{5q}##k#f7IG4{MEBzeT&CEKRH znbUEOzJlBjq@2lWfn4N8y6AcVA8MPSCArNe0=k(m&!Qda@8B~0xE(a|7f0=|zmd8? sW<4k}ogk*6ZN{16PHi*y&}7H$SpU>nUS^YYN6I~pabGco08P371H4&**Z=?k literal 0 HcmV?d00001 From 432ecbf43e51f648222a2a0ebb3a3de757d0a372 Mon Sep 17 00:00:00 2001 From: Genvictus Date: Wed, 26 Apr 2023 18:23:18 +0700 Subject: [PATCH 024/101] fix: split filename with extension now handles file without extension properlu --- src/user-shell.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index 92db9a1..bac1298 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -183,8 +183,16 @@ int split_filename_extension(char *filename, int filename_length, int words_count = get_words_count(temp_index); if(words_count == 1) { - if(temp_index[0].index == 0) return 1; // filename has no extension - if(temp_index[0].index > 0) return 2; // file has no name (why?) + // filename has no extension + if(temp_index[0].index == 0) { + if(temp_index[0].length > DIRECTORY_NAME_LENGTH) return 3; + // copy name + memcpy(name->word, filename, temp_index[0].length); + name->length = name_length; + return 1; + } + // file has no name (why?) + return 2; } int last_word_starting_index = temp_index[words_count-1].index; From 336cea97b990c355c656b99341db95c998e4d8a8 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Wed, 26 Apr 2023 18:28:54 +0700 Subject: [PATCH 025/101] feat: add ls condition --- src/user-shell.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/user-shell.c b/src/user-shell.c index 0bca3e1..b4a2bd8 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -697,7 +697,8 @@ int main(void) if (commandNumber == 1) { - ls_command(current_directory_info); + if (argsCount == 1) ls_command(current_directory_info); + else syscall(5, (uint32_t) too_many_args_msg, 20, 0xF); } if (commandNumber == 2) From a67b52fa743e59da5dd0b95498fa25689c3c5d12 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Wed, 26 Apr 2023 18:37:31 +0700 Subject: [PATCH 026/101] fix: vscode configuration --- .gitignore | 1 + .vscode/c_cpp_properties.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..600d2d3 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.vscode \ No newline at end of file diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 8bc661a..a0aa6ea 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -6,7 +6,7 @@ "${workspaceFolder}/**" ], "defines": [], - "compilerPath": "C:/ProgramData/chocolatey/bin/gcc.exe", + "compilerPath": "/usr/bin/gcc", "cStandard": "c17", "cppStandard": "gnu++17", "intelliSenseMode": "linux-gcc-x64", From 7f118860ddd77e5da5c63972c74ada1d2e6831bb Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Wed, 26 Apr 2023 18:49:21 +0700 Subject: [PATCH 027/101] fix: remove kernel warnings --- src/fat32.c | 2 -- src/interrupt.c | 30 +++++++++++++++--------------- user-entry.o | Bin 1408 -> 0 bytes user-shell.o | Bin 21712 -> 0 bytes 4 files changed, 15 insertions(+), 17 deletions(-) delete mode 100644 user-entry.o delete mode 100644 user-shell.o diff --git a/src/fat32.c b/src/fat32.c index bf55714..fdcd2b2 100644 --- a/src/fat32.c +++ b/src/fat32.c @@ -785,8 +785,6 @@ bool is_requested_directory_already_exist(struct FAT32DriverRequest req) { read_clusters(&driver_state.dir_table_buf, req.parent_cluster_number, 1); - bool is_creating_directory = req.buffer_size == 0; - // Iterate through the directory entries and find the same folder/file. Return // early if file with the same name already exist. bool same_entry = FALSE; diff --git a/src/interrupt.c b/src/interrupt.c index 40d797d..b7a8693 100644 --- a/src/interrupt.c +++ b/src/interrupt.c @@ -72,22 +72,9 @@ struct TSSEntry _interrupt_tss_entry = { .ss0 = GDT_KERNEL_DATA_SEGMENT_SELECTOR, }; -void main_interrupt_handler(struct CPURegister cpu, uint32_t int_number, struct InterruptStack info) -{ - switch (int_number) - { - case PIC1_OFFSET + IRQ_KEYBOARD: - keyboard_isr(); - break; - case 0x30: - syscall(cpu, info); - break; - } -} - void puts(char *buf, uint32_t length, uint8_t color) { - int counter = 0; + uint32_t counter = 0; while (counter < length) { @@ -114,7 +101,7 @@ void puts(char *buf, uint32_t length, uint8_t color) else if (buf[counter] != '\0') { - framebuffer_write(row, col, buf[counter], 0xF, 0); + framebuffer_write(row, col, buf[counter], color, 0); // Handle wrapping behaviour if (col < 79) { @@ -194,3 +181,16 @@ void syscall(struct CPURegister cpu, __attribute__((unused)) struct InterruptSta } } } + +void main_interrupt_handler(struct CPURegister cpu, uint32_t int_number, struct InterruptStack info) +{ + switch (int_number) + { + case PIC1_OFFSET + IRQ_KEYBOARD: + keyboard_isr(); + break; + case 0x30: + syscall(cpu, info); + break; + } +} \ No newline at end of file diff --git a/user-entry.o b/user-entry.o deleted file mode 100644 index edf2aadd2e5bc828ba5b263eb2f44167a7d10b37..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1408 zcmb7EJ#W-N5S{fU;gCq=goq%4P#Oe6!jOm*d$Ds3AQgH6%l`c zo{EB!k{abFz}&%5JWCk0|ov%B-=?aZ@xeQzH=S~13mnvsr-B9UdExKYoS zC6-f4{jZrd=@Wj}K_qe_s1W-#v9SLkc=G{Ib7z2!1^5r}&LWpjIwy8uj0`+fm%QbEi+;PE;6yyUPR<8Qx*!{PToSUEe7$>|`&S$NN=#drbK zV?xo0@5255T8i#1i?wTm(iT^3UKM*uDNpV{dpy6GEG#A0m&EKJDT6A`>V94d&qw=( zy=RH@^1yDwmBZLf<2PgCiB9)o_cTaRBGYD>Wox^QF_KFdjrlb-iLw5eq20(a&GnA) zTI$@3C<0mdU5EW7sqC9dl2# zWrf{U>Q*neEvf??b-h5j!KNdY=f6$4DKqgGL?tw8lw18RnHQK`kpzZd_cnzm4KYpznEUfTSBYoC246F}>~-@X6u z`+uK@Z)WZF*lVw~_S$RjbIycK_L5nOqA>GPn8x}r##S#dIM)g=lBKf&Y)RnvLAy2Z zdeEK}I25#}1r7)8dZ7KS!W}DL2hZ1?)M4+9ZMFB-C)O)v_5Ae3-rio{8%aBUCD|eS zMN)TmSkQj4HSJAmLqn@o{h??MumA*6Hrg)=;SA+?zMW ze~rg6=BT5AGN`;@xP5M8YJWTYMToi)vPHh`G~dP~+g;HILF+v`D`Y%Bw>uCxZ1=*n+>-IlTi3(a}+w|jZee(r3d&wftvZ9Eru*Aby7xbmWyQA~mF zLa#RgNdeL5gOopK`9V@>CWJZTku$ohoLur_cBHmi2mdDU>ED z615;r;H%=z4GKwk7ArhEvy}oRX^5yw-rkP*_)aUqZEup+fW0S-cMBXT*aLpRe%iP3 zw7x0Ix3OD8Uyb@+7X%dnhbg_@B-7*|(zdjRX5%O^7xsG7OqPhO2+Y!37H#QfNyuF5 zFm~nEF}U37?|>D*h(hxfjK~5Rfff42R%Fk|7e^ge4*7m}@z5DH@Im0i&!6#ilNCmf zaQuATR!}}gyi6M~AHgyUeKRl@mem(Xfxdv+LiR2iO$dn^p&ZBRDK1F#$8jPjIYXOi zMpbHuHq(^Rb>=^?{)6@|1oJ3{^j%QAIR;7=L@3Jl#`x@A%9&qYBCjU;d!XmCK8Rzz zTDuwP8Fs_pp6GuAvWW-mN1eV4YT~vAC~Mt4Ce+(|@KH$qLgZIQAS;N71y;mfY+YvY zeR6TsZxOd&%eWm4oCb1s3ujCYqQoQh+37W%W_vfD5ew`-!0aMB;&IST)$n?bf z9}+{agQl5vE=S1!9ki-E&90Dt6I$zSO_d?P53NRrtuEx>j+WczX%6{=Xf@j!(E2V~ zO*NBj9sUQBqoA{%43blGKob%i=`Dfc>};oYvix`iD9-ctKpf=Ews}a6kbecRS(SASA^&Q$9Mv{Y$X|_C zvyB2?i&kZ|tvcjyKnrtF74o;Bg*jLc4?Sp7Y}W$971D*+4vGj^*i_K<2)ZyQ=qFof zaV!e?XQOF%xiDw*&~i<(HHG{)qt)!OVU`!6Wpg&e%%x~mJ6y3H{^e+4RO$%r10uAa z*$>}L?N~}b7OswgpfN%LS{MOtjYG?DYXVy2R>(gYEn8DF0x^|Z&Sr1OKLf3%>R6g~ zv@RWPwir%MTFBl>snB6R#m*e1oUngL_!&y(puO`@XB?&3aoSNoJk-f)Gd~uQf=Ih? z3PMCDxnr331$|oq>i8TG6ZcPxD^Bv>K+V3@bZNGo3%Bf16r)H(5h-wI7)$#en_`MdBDy1!;4u8fn&^%qzmwrA>TM@9DfVu|!5)}_j3F8TDUi8A=c#x4I`}SN zhuBNX{C8o?n$xrvbz&=84RzJFkpFJ9njGuUx)-f#v47l;ma%{AM9bJe9z?6rkpsE! zqg7gY2X>OZMDsR+_9L_=*s5wn{wL9@bXB4NK8=>g;c}w@K8I!wiUJu>pIA$`9g$@y z0S7BgI8F87;F8mFHJ=`1?@rvGa?dV)0?zsDICCKiyM)J(R*p}^Bpz?|zl}BX%?>wT#U-{vyJ8uio43Utyv zQg>@vZ(vDh;P645(`aQV$6uq?%lNSK=WlDrP1Kg(u^z0gk4GJyc*2t;4|4YnyO;=( zv)zHiTR!eZbJPj5<$u=`pGzd)X^Yb7(=n89mB(GTGj};S_SNwTzC+(kC1+Pnr${PPY0FU{?N#8u2!|1w?1m2nwI55gnk0{73Ok zHA0kxRzFQ3B1!}GFAP5g#h{DApqgg2IxZ|Xs@p$an`Kv8n^>eO7GtZQ)`vNZU$y## zOuyA9?wPO%aY7WU?;KVi&AWoLy-`7o)kieB2rpTEC}ot)xEl~#Q}-BqkCDtDqKgmd zizR~#VB+``bLyTlK!`VMgdqkRc{Xa?5&XD~yWk02< zSlD!55G?HkW~3>t>eG|$J^j*D_=Gg=G##KceFeGlPo(L)=oS#2k*4n>G$KtYK|_8@ z;fOS)sX?03K>gG7=b#vLk*3TvE9fT<_OGm<=yiE*J3H{;qcMzK&e+kH;)`0h4P!s; z?d`j(oA`$JGhg?$9rp7mnr}V-Px;-2ZUNC5>p$Q>2{h#I#5XH5)};j*Z)orD>=DQq z^h-Bu;?QkWmN>_eT`1XoTNTaonN#>eX`=1=%un%UY*yWJ*FH_Vc9+<-sWgxY;oLpQdAa4|OKd*-@xCg!EGIB?dj>YbTjl$k0uK z9`Q^750B2%vh;22nz}A?^TzYcn~JXCQ(jNv*0ESthDdkJSBR((N!)KgZ=Ni^;$Sfh zCCj%_SG|J|K7YmRIP*S2*XsZ1gMVu3&!JmDbVl_F_`89I{5|*w4W3= z=O3c+ve^3ngsuP8zODa@|JJP^&jmWMddg~FK<@N!6qbSi2B)IdW=}aNFE9)TtflQ_9QDN;xgOM4rmp54HMELOu#^jcO1&nmTtPU z!kH3xVj`Or9FXzMuH*A30zH8*6A$RlK&%MymN$|}^5mIGf5YlVHsAud;#F0BMRJ(f z;0`yh*l4^BcL!JG7{sbd&)0Ant7`dLHgh$8J->17*YnraI$Vyrf8fN|tN0(~=I8&9 zs{dB`w-NX@0^dg9+X#Fcfo~)5|6v4X)ipTieG0uvX{u%g%-QU^t*)si&r|DiR95HB znN?IYu5c0?#!kgE#+gD7rr~IN^$a9$(SvWAU9}iGBx1$oLL?Sp_Bj zB$~+?^NFcOPsW?Ncsp*p(g&_4ilR4>_#+?>N~1Ghj)m7Xc~~m76IA|$5Q=({gw~@wO>Cl?}KKRu0tKvJeIlwFhFT zDdVzB#Kj`wvRlN(YWWqZdr(-FXnBi#d`KXv>}pFU_0{f&dJ3zsG){bHv(y|=vNnJf zZzU!t6IogznW8I$H-ls;1)>azr8XOM3k0&sccu?Ig)wb2(8Oze;p~GD5sG_dI0pP4 z6kQqiOVYC$lFINHalc@>6%=KJKrAflerO$?Lfs7m27d(E!O>**f8diin7%%vui;>@ zr1NNI5@*=p5Ud-?N$Ef+NfhGZOGsWtFA#561;0Fvu_cgE_QWAR%1|`jYT|kbsNU5o z<)%lCC6?wrwo##9XL!~0K?dHaS*GWoMex{ zQw{m~z(p0%yya0W_igl0+ZtffS~geN zK*&*JX}mSbjQzW?L5dwoMuU)D3GTIVTSZbRkmLmL~vgD{hb)^$lom7lWZTqkp*8ENp3k#uDR${o1O|(|ofxw+n zVyUibZO5Axib{`SWO3Wk3W}9x&gs$bZc-8;Xfb2;GY}|N@n)>{eRosL1iXhLCm$ed z>e-)^1d)kt)r`Lb7QG2m{u7IEgmkY5cvi83`wEGdfB z$B;L2vTX%&Qh}BY$|tdm?LkY~GYXG6M5Hz-S&@<2pp1=-)COf~WTfskBXxoz73>QQ zMe05itycaG=)-2Djv0~qkr}BD5vhZU%>E7pW;IOzg(9>6c^Rq0ip>6}5UD|NjE#WS zUq%bhx0sP?U@^zQqW7^UiA76&w~|2aS=zq1e-n$Tw;C}%PwaZO$LzV9@sZf~!!h2c zBuqpvt!;4>e;5oI<7dqnQyPluKvE(B#~OGEa2aV@{ZvWkD?h{&z8f(O%AQZb7Fjo6 z$)nl9nxjl9GyU&;ev|Sl=nG8$e+2?%$}-dcH?aEaFmv=cNTC|LT9K>28nduQG3p`m z)q**%GSSt1JNnRp1YXxDMvZH$1wK%NVTZS4h%9ta_Iw|5akOd<50t48O^fDmzRZMZ zS~G_i%S6y$f(38Ntbesxe+}pnxqx1+u-37+BBd!KjD9;RM3ISCMj0J% z5^+mW2Gn2}t?j-Fc%G-E8)c+ixdZ0pD=9{4TN?8;#vprA;J%ge=F4=7gx2=yDi#xs zY@uH&)q*0DDnm(sT5wOSirE1s1-29fWj`9(O4iGQ`PwSRKLd9)h=P-=WE~Zp$5vr~ zz74r>6fE^NR-_Ct)@~VJ2Pzq&>_$w+D`S6)4r<#>P>cklaYe$(BNGiJ@GOH*0|-3L zz^T8$2eG8XP?E6$dY_`vUP9wtKxNN5ESl&)!ojD8nREUN#N(+V!zfEM9cZ4KWAOCo zY;<~RiGf-5T=aWJPI+guegYHqoLMw=q!fEeVzqh+u>BIN)*nR2gA!YfJj58g>0~@x z*z^?HGz!h#6O3GA(O;6pG6S=)jAAhFBMb9DpDsFmM4c#I?;ByHE7R}AJl`)z@vz*x zNp5=-O?y1#Y@%BfszUUi(cC_g>LwN?%b?%HtR?Nwp-~~kDj+77#@ZofnBIi9Ye$%2 zDn{qElMPJghtY95I${;vB};h&)>|54a?2B-$AGWw`Pfu?OSY+$9Jpn?x!$@Uddp0z z;%ZxUG!1ymB4Y?^^gxoVF|Z_zv(j`FNyOMHi8Y8IR7k9aWe1?F>^qPcjStE{3Y_q( zEYmcB4wYp?rC)pt#BBIrgoV-*l%MQ;kZzicuW9%wd)7dW2>wmOW$^iQFvjD9j&u7u ziiNM-7&RCi$|Ysbc68N$2G?fBQd4bPXC&`KKt%GQ-Y0^s6i`CpZh<<*IV$g91;#0_ zjm0_E0LwL&w2Z!~VABl@@m8*7TEe6pWip=_Hz!riz=)ve{V1BE%t=*n z%(BFjaNOiLlD!@Y#^aP^B?X2=<*+%a1(b4J>Ju`gPd7&hQ(}x>q%qbM4-b#u@fyR2 z#jU16VM=_u7(_J;!QI#}78iFzoR)yII)@?H?-N;Ej)hvuuo>=XeMYC`D^oK~r*oo4 zWReThGB#wAL8-$<|Fl#^ONisb*BqS~0|X^5f|4$LhKB?D6vj=wRAELxCLfVGCpB`s z%n4$=tbRe7nn{5hB%+O}fzkxT8)ay)smwy|kgj53^;ITa%;TkF3^79*4sv#%e5A#9 z3T3urB{v~8PRkyYO_nAN#5q_77;9;$@EW#UjSyqPhYd#t=1P4cHTs4(^bL<>M*2P? zl3`B6otZMLvFvc6WXa2X+(78xv6XP}Xi?!$P5vt(o`6D_AY^M)5o_?d4Ifp>RulQ1 z#NAF`yNE_7BlSu8;tJzpFs(r0e9H3W%U5!xU@DKT;d~xf^qi?Y0Zk82VyZ0{d?;a)!&2Kyc}#oFvz)KxanJFD<$UZMZX*p_c@}|v zd;)-4&c_ni$E~G&2+?2W83sGa&xdsJ#AQ68;2-tPE9KXA@uYk{tcz!t^Mo6Cx_0|q zKA043<>`h#MN8f~mFsu#q#B;Emb{EF-% z_wq4&d3-(3)OYeECr{r7Jte97JTR_W#?zcUYZ)J)PE6%P^#^z+(49bMr6Sr7^7J;I z;^nC&e84h3a4ny)jE_CSmp{id_wpI}eC*3Sx147d^NjcT?d05CUPr*gr*eCjv#H(>$!N6|9J z-D+S?WB7mQAJ%Ic94h_qaY*LK=n|?PiawmjTmw+6#cahG&+_aN)Q4L#u{_LV+Qw6M z@_}9o-k@bX-ouA1q+W0c5r2$ z7F&*p9OW^!n6($k>a4KMB|G`GdwFR&pS+jH>VhDMJR<@ zjC!4d6v3oc{DHfje71)Nkyfe2w1vc|EorC?wdDJE$dp2n?%Ml&24N^Q1j_k*0{SF= zJs_5Z*yEhMcqKxtuhnnRz4}^yl{z#HX>@fOPpRecYEde`O5e?sP{Pt``G6XftXBZk z+%(Wid2%gmD}!w+UP&kob&Yi%)==s8RIF=uRadw@l`aonVpP;MRXgrrc)IUsa@RFC zv1*6g!(0xx!(*@zOf3ox7si;jHvFNad`>h1VAq_?>%0U6X^kYnxpj8@%$;i+qMFi2NGe??OzkjBcoCf4X^tZG>g(}kA~moXabcQ&(1kH=NF#_Msgs%qHZ zh+nEz!@tVv3YX({FF8xPJe6x29L(crY>@$(;dQwjO`e&iA9F~T7p7egvsx-WwQknf zTwUj^b5vJUS3)~nGu{tXHF(|ld3{A~T}>@p)7;#^Yw=R8H7QE|?*kIcK4L z#^Re7-dZtp&Z4rC>92I)`#u%#@K=G*8Uk>~&QkQRr7vW=NQOy}PQip@B6}P8&IKdHiplHEWT5 zvCPVTBf1=(s^)5>l#wMBG!PWg;xN5vXkN#J_x-17u}Czz2>R?b{i;G{B90=XXjL$= zSj`AsvS=gMBrOVIg(=&&CY_jhSca4|;*B^MR!9*s#~xSZTKr82hL#CZhZ!+Uch!Nj zP%akJV^eIsTxG`kH0-Wuc8Z}$giF&e_Vc{Ew6E05xzX$CdZT-N0Y-21C2`e`lhN{S94Rd*PZ8WT8CN46E(#RrqQno#kbb%O_kQDIbJs$?kiFEQ(tXH68?6l5HjXV*su)jQ!g4ZC!ZHX#(cHSW?B_CCyA?G zHZxK4wnQaGtKJPsQL6WjBu(|w+n0V9%ne@__Mg3B1daax6A0mWk`!@iOgz;LQ#A80 z_$5VSc;pmuX$+4=BQA|4;Gc1Ah9Sw&KS<(ucm-Tz&86Hf2+%$z2ier{~$FyTJn=7o2X>|T7#{3ZUwz|DLm{2Ab8eiHr~aPy-69r&2} zN&Hj5&3q*MPr%K5Bm6JG&DnpJ#4$SJ^wj@&6?tU6 z;>jZ7d?rrt^urw$sk$6c!E2{V3Ev_*Qucj>Rl(c8Gk_|7hOi3jO-;euBZBz##&Lpp z(|w8{o<6U_6Mv$wm+&k>6n^^g0O`v?Jtuj3AxN*Z-yj@%PfNTB%Z%*dSY8ARCA^*> zUIRQR@goE=&Sw&@j5g%gOSpv~OV=snSd0(MG`+t5ON&4NX|hJv@U{!u#PY{B!4>~@&6#9 z4P&Y(Fe3qpKY?)YOC-EN5Vl4`H`%=xkmQ~u9G^}Jqw#|rqT`K+pyv>To{17JkkCyK zK0ZJYzI`I;UlN2(!{9UdeY1p4g3z;vAiboa{6vnx6sBNq;T}^!M0WwR2qG7U5=3r{ zAPBi@C7dYXObHiAc#DKp64pw%MZ$X|Y?bhP6230sI})Cj@Glaow0(*@Z>D;I@slBlJq}I{BIIkkz1s9jD*D! zmJ-A`w@BO}p-0m1m5|=SQ~%c_{*lDHCHyZ5Gmx7kN57{eI6=at64pw%o*>5ECE*Vw z{aJ~BBJnd4r=LBLzH|w5CA?9>1rkh14-|Z_+KQRf?TC>Y!c>6I7Py8f*9W;ai4@#$BF)o#9xu{ zsDyu%@C$;FOGPddER=8xL5w?J;!7n?Ki?s_O%mQC>75duk@O1^k3!8NJ!ujSm9S94 zsS=h-xLm?I3Ga|_BSDONpTxf};ZG!dQSuK-{2dAZw}fXT|ANG$v0ss0Nd%!cPvVm$ zoFnP0CGL>;R*CPBaIb{>B3iuw<_sQ-XBNcs#3Z<25!LFlmos({lZTrJ^d z2_KcPUBWI2EvUoPkIt$DXG&Nt;Vud3zf&WAmxM`Z6Mn6PBrCKU_By{$q&kB(+`o8 zW@o@>3vm7o8__q`GVn~@BtD~vF&j1HW%B5Z6FKf1H)CATXk4P3<2Isg_Cb?XL7y5C zK$BMoUZlPg&__0tK9rlVKKd~@^`SV@<(Oog>kZ7{5q}##k#f7IG4{MEBzeT&CEKRH znbUEOzJlBjq@2lWfn4N8y6AcVA8MPSCArNe0=k(m&!Qda@8B~0xE(a|7f0=|zmd8? sW<4k}ogk*6ZN{16PHi*y&}7H$SpU>nUS^YYN6I~pabGco08P371H4&**Z=?k From 1abd95f93053775c6ac0d11eec8c8ab218f915a3 Mon Sep 17 00:00:00 2001 From: maikeljh Date: Wed, 26 Apr 2023 19:20:16 +0700 Subject: [PATCH 028/101] fix makefile user-shell --- makefile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/makefile b/makefile index 822cf11..a1d373e 100644 --- a/makefile +++ b/makefile @@ -78,15 +78,17 @@ inserter: user-shell: @$(ASM) $(AFLAGS) $(SOURCE_FOLDER)/user-entry.s -o user-entry.o - @$(CC) $(CFLAGS) -fno-pie $(SOURCE_FOLDER)/user-shell.c -o user-shell.o + @$(CC) $(CFLAGS) -fno-pie $(SOURCE_FOLDER)/stdmem.c -o $(OUTPUT_FOLDER)/stdmem.o + @$(CC) $(CFLAGS) -fno-pie $(SOURCE_FOLDER)/user-shell.c -o $(OUTPUT_FOLDER)/user-shell.o @$(LIN) -T $(SOURCE_FOLDER)/user-linker.ld -melf_i386 \ - user-entry.o user-shell.o -o $(OUTPUT_FOLDER)/shell + user-entry.o $(OUTPUT_FOLDER)/user-shell.o $(OUTPUT_FOLDER)/stdmem.o -o $(OUTPUT_FOLDER)/shell @echo Linking object shell object files and generate flat binary... @$(LIN) -T $(SOURCE_FOLDER)/user-linker.ld -melf_i386 --oformat=elf32-i386\ - user-entry.o user-shell.o -o $(OUTPUT_FOLDER)/shell_elf + user-entry.o $(OUTPUT_FOLDER)/user-shell.o $(OUTPUT_FOLDER)/stdmem.o -o $(OUTPUT_FOLDER)/shell_elf @echo Linking object shell object files and generate ELF32 for debugging... @size --target=binary bin/shell @rm -f *.o + @rm -f $(OUTPUT_FOLDER)/*.o insert-shell: inserter user-shell @echo Inserting shell into root directory... From 3e30e75c032a8d526fe542bf641d9b79fd5e8366 Mon Sep 17 00:00:00 2001 From: Genvictus Date: Wed, 26 Apr 2023 19:34:02 +0700 Subject: [PATCH 029/101] add: syscall for eax = 3 as delete file --- src/interrupt.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/interrupt.c b/src/interrupt.c index 40d797d..6ff5cdc 100644 --- a/src/interrupt.c +++ b/src/interrupt.c @@ -159,6 +159,12 @@ void syscall(struct CPURegister cpu, __attribute__((unused)) struct InterruptSta *((int8_t *)cpu.ecx) = write(request); } + else if (cpu.eax == 3) + { + struct FAT32DriverRequest request = *(struct FAT32DriverRequest *)cpu.ebx; + *((int8_t *)cpu.ecx) = delete(request); + } + else if (cpu.eax == 4) { keyboard_state_activate(); From 0780b93d2c2f64c31b19a81b6dfdd946725b941b Mon Sep 17 00:00:00 2001 From: Genvictus Date: Wed, 26 Apr 2023 19:34:20 +0700 Subject: [PATCH 030/101] feat: cp, rm, &mv command prototype --- src/user-shell.c | 138 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 132 insertions(+), 6 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index bac1298..9028c9d 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -9,6 +9,7 @@ #define DIRECTORY_NAME_LENGTH 8 #define INDEXES_MAX_COUNT SHELL_BUFFER_SIZE #define PATH_MAX_COUNT 256 +#define MAX_FILE_BUFFER_CLUSTER_SIZE 512 // take arbitrary size of 512 cluster = 512 * 4 * 512 B = 1MB #define EMPTY_EXTENSION "\0\0\0" #define EMPTY_NAME "\0\0\0\0\0\0\0\0" @@ -172,13 +173,16 @@ void copy_directory_info(struct CurrentDirectoryInfo *dest, struct CurrentDirect * 2 - if file has no name * 3 - if file name or extension is too long */ -int split_filename_extension(char *filename, int filename_length, +int split_filename_extension(const struct ParseString *filename, struct ParseString *name, struct ParseString *extension) { + name->length = 0; + extension->length = 0; + // parse filename to name and extension struct IndexInfo temp_index[INDEXES_MAX_COUNT]; - get_buffer_indexes(filename, temp_index, '.', 0, filename_length); + get_buffer_indexes(filename->word, temp_index, '.', 0, filename->length); int words_count = get_words_count(temp_index); @@ -187,8 +191,8 @@ int split_filename_extension(char *filename, int filename_length, if(temp_index[0].index == 0) { if(temp_index[0].length > DIRECTORY_NAME_LENGTH) return 3; // copy name - memcpy(name->word, filename, temp_index[0].length); - name->length = name_length; + memcpy(name->word, filename->word, temp_index[0].length); + name->length = temp_index[0].length; return 1; } // file has no name (why?) @@ -202,10 +206,10 @@ int split_filename_extension(char *filename, int filename_length, if(name_length > DIRECTORY_NAME_LENGTH || last_word_length > 3) return 3; // copy name - memcpy(name->word, filename, name_length); + memcpy(name->word, filename->word, name_length); name->length = name_length; // copy extension - memcpy(extension->word, &filename[last_word_starting_index], last_word_length); + memcpy(extension->word, &(filename->word[last_word_starting_index]), last_word_length); extension->length = last_word_length; return 0; } @@ -640,6 +644,128 @@ void print_path(uint32_t cluster_number) } } +void cp_command(struct CurrentDirectoryInfo source_dir, + const struct ParseString *source_name, + struct CurrentDirectoryInfo dest_dir, + const struct ParseString *dest_name) { + // prepare buffer in memory for copying + struct ClusterBuffer cl[MAX_FILE_BUFFER_CLUSTER_SIZE]; + + /* READING STAGE */ + + char nameword[8]; + struct ParseString name = { + .word = nameword, + }; + char extword[3]; + struct ParseString ext = { + .word = extword, + }; + int splitcode; + + // split source filename to name and extension + splitcode = split_filename_extension(source_name, &name, &ext); + if(splitcode == 2 || splitcode == 3){ + syscall(5, "Source file not found!\n", 19, 0xF); + return; + } + + // prepare read file request + struct FAT32DriverRequest read_request = { + .buf = &cl, + // .name = EMPTY_NAME, + .ext = EMPTY_EXTENSION, + .parent_cluster_number = source_dir.current_cluster_number, + .buffer_size = CLUSTER_SIZE * MAX_FILE_BUFFER_CLUSTER_SIZE, + }; + memcpy(read_request.name, name.word, name.length); + memcpy(read_request.ext, ext.word, ext.length); + + // copy file to buffer memory + int32_t retcode; + syscall(0, (uint32_t)&read_request, (uint32_t)&retcode, 0); + + if (retcode == 0) + { + // read file to buffer success + /* WRITING STAGE */ + + // split source filename to name and extension + splitcode = split_filename_extension(dest_name, &name, &ext); + if(splitcode == 2 || splitcode == 3){ + syscall(5, "Source file not found!\n", 19, 0xF); + return; + } + + // prepare write file request + struct FAT32DriverRequest write_request = { + .buf = &cl, + // .name = EMPTY_NAME, + .ext = EMPTY_EXTENSION, + .parent_cluster_number = dest_dir.current_cluster_number, + .buffer_size = CLUSTER_SIZE * MAX_FILE_BUFFER_CLUSTER_SIZE, + }; + memcpy(write_request.name, name.word, name.length); + memcpy(write_request.ext, ext.word, ext.length); + + // copy file from memory to disk + syscall(2, (uint32_t)&write_request, (uint32_t)&retcode, 0); + if(retcode ) { + + } + } + else + { + // try read folder + } +} + +void rm_command(struct CurrentDirectoryInfo file_dir, const struct ParseString *file_name) { + char nameword[8]; + struct ParseString name = { + .word = nameword, + }; + char extword[3]; + struct ParseString ext = { + .word = extword, + }; + int splitcode; + + // split source filename to name and extension + splitcode = split_filename_extension(file_name, &name, &ext); + if(splitcode == 2 || splitcode == 3){ + syscall(5, "Source file not found!\n", 19, 0xF); + return; + } + + // create delete request + struct FAT32DriverRequest delete_request = { + // .name = EMPTY_NAME, + .ext = EMPTY_EXTENSION, + .parent_cluster_number = file_dir.current_cluster_number, + }; + memcpy(delete_request.name, name.word, name.length); + memcpy(delete_request.ext, ext.word, ext.length); + + int32_t retcode; + syscall(3, (uint32_t)&delete_request, (uint32_t)&retcode, 0); +} + +void mv_command(struct CurrentDirectoryInfo source_dir, + const struct ParseString *source_name, + struct CurrentDirectoryInfo dest_dir, + const struct ParseString *dest_name) { + cp_command(source_dir, + source_name, + dest_dir, + dest_name); + + rm_command(source_dir, source_name); +} + +void recursive_rm_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInfo *info) +{ +} int main(void) { From cfb46299e5b1bea96766074b56d7834058bb79c1 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Wed, 26 Apr 2023 19:36:17 +0700 Subject: [PATCH 031/101] fix: delete writing command --- src/user-shell.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/user-shell.c b/src/user-shell.c index 0da0c1d..e469e08 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -694,7 +694,6 @@ int main(void) syscall(5, (uint32_t)directoryDisplay, DIRECTORY_DISPLAY_LENGTH, 0xF); syscall(4, (uint32_t)buf, SHELL_BUFFER_SIZE, 0); - syscall(5, (uint32_t)buf, SHELL_BUFFER_SIZE, 0xF); get_buffer_indexes(buf, word_indexes, ' ', 0, SHELL_BUFFER_SIZE); From 4f46d6d0fe7b977365e18aa8d1bf46d527de1998 Mon Sep 17 00:00:00 2001 From: Genvictus Date: Wed, 26 Apr 2023 19:53:23 +0700 Subject: [PATCH 032/101] rfc: ParseString contains array of char instead of pointer --- src/user-shell.c | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index cfea4c4..60af294 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -51,7 +51,7 @@ struct IndexInfo defaultIndexInfo = { struct ParseString { - char *word; + char word[SHELL_BUFFER_SIZE]; int length; } __attribute__((packed)); @@ -164,6 +164,11 @@ void copy_directory_info(struct CurrentDirectoryInfo *dest, struct CurrentDirect memcpy(dest->paths, source->paths, PATH_MAX_COUNT * DIRECTORY_NAME_LENGTH); } +void set_ParseString(struct ParseString *parse_string, char *str, int size) { + memcpy(parse_string->word, str, size); + parse_string->length = size; +} + /** * Split filename into name and extension * @param filename original filename before split @@ -546,9 +551,11 @@ void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryIn .buffer_size = CLUSTER_SIZE * 5, }; + struct ParseString target_filename; + set_ParseString(&target_filename, target_file_name, target_file_name_length); struct ParseString target_file_name_parsed; struct ParseString target_file_name_extension; - int split_result = split_filename_extension(target_file_name, target_file_name_length, &target_file_name_parsed, &target_file_name_extension); + int split_result = split_filename_extension(&target_filename, &target_file_name_parsed, &target_file_name_extension); memcpy(read_request.name, target_file_name, sizeof(target_file_name)); if (split_result != 0 && split_result != 1) @@ -671,14 +678,8 @@ void cp_command(struct CurrentDirectoryInfo source_dir, /* READING STAGE */ - char nameword[8]; - struct ParseString name = { - .word = nameword, - }; - char extword[3]; - struct ParseString ext = { - .word = extword, - }; + struct ParseString name; + struct ParseString ext; int splitcode; // split source filename to name and extension @@ -739,14 +740,8 @@ void cp_command(struct CurrentDirectoryInfo source_dir, } void rm_command(struct CurrentDirectoryInfo file_dir, const struct ParseString *file_name) { - char nameword[8]; - struct ParseString name = { - .word = nameword, - }; - char extword[3]; - struct ParseString ext = { - .word = extword, - }; + struct ParseString name; + struct ParseString ext; int splitcode; // split source filename to name and extension From 5a81a57ff58ee22a9f68d94f7e8d00bad77ffcbf Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Wed, 26 Apr 2023 20:39:52 +0700 Subject: [PATCH 033/101] fix: out of bound error --- src/user-shell.c | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index e469e08..9002b70 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -45,7 +45,7 @@ struct IndexInfo struct IndexInfo defaultIndexInfo = { .index = -1, - .length = 0, + .length = 0 }; struct ParseString @@ -79,12 +79,18 @@ void print_newline() syscall(5, (uint32_t)newl, 1, 0xF); } -void reset_indexes(struct IndexInfo *indexes) +void reset_indexes(struct IndexInfo *indexes, uint32_t length) { - for (int i = 0; i < INDEXES_MAX_COUNT; i++) + + uint32_t i = 0; + while (i < length) { - indexes[i] = defaultIndexInfo; + indexes[i].index = defaultIndexInfo.index; + indexes[i].length = defaultIndexInfo.length; + + i++; } + } void reset_buffer(char *buf, int length) @@ -104,8 +110,6 @@ void get_buffer_indexes(char *buf, struct IndexInfo *indexes, char delimiter, in int limit = i + buffer_length; int count = 0; - reset_indexes(indexes); - while (i < limit && buf[i] != '\0') { while (i < limit && buf[i] == delimiter && buf[i] != '\0') @@ -219,13 +223,13 @@ void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf copy_directory_info(&temp_info, info); struct IndexInfo param_indexes[INDEXES_MAX_COUNT]; - reset_indexes(param_indexes); + reset_indexes(param_indexes, INDEXES_MAX_COUNT); - get_buffer_indexes(buf, param_indexes, '/', indexes->index, indexes->length); + if ((uint32_t)indexes != 0) get_buffer_indexes(buf, param_indexes, '/', indexes->index, indexes->length); int i = 0; - if (buf[indexes->index] == '/') + if ((uint32_t)indexes != 0 && buf[indexes->index] == '/') { info->current_cluster_number = ROOT_CLUSTER_NUMBER; info->current_path_count = 0; @@ -409,7 +413,7 @@ void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory } struct IndexInfo new_path_indexes[INDEXES_MAX_COUNT]; - reset_indexes(new_path_indexes); + reset_indexes(new_path_indexes, INDEXES_MAX_COUNT); // [path_segment_1] [path_segment_2] [path_segment_3] ... get_buffer_indexes(buf, new_path_indexes, '/', indexes[1].index, indexes[1].length); @@ -495,7 +499,7 @@ void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryIn buf[2] = ' '; // t struct IndexInfo new_path_indexes[INDEXES_MAX_COUNT]; - reset_indexes(new_path_indexes); + reset_indexes(new_path_indexes, INDEXES_MAX_COUNT); // [path_segment_1] [path_segment_2] [path_segment_3] ... get_buffer_indexes(buf, new_path_indexes, '/', indexes[1].index, indexes[1].length); @@ -676,7 +680,7 @@ int main(void) while (TRUE) { reset_buffer(buf, SHELL_BUFFER_SIZE); - reset_indexes(word_indexes); + reset_indexes(word_indexes, INDEXES_MAX_COUNT); const int DIRECTORY_DISPLAY_LENGTH = DIRECTORY_DISPLAY_OFFSET + current_directory_info.current_path_count * DIRECTORY_NAME_LENGTH + 1; @@ -719,7 +723,7 @@ int main(void) syscall(5, (uint32_t)too_many_args_msg, 20, 0xF); } - if (commandNumber == 1) + else if (commandNumber == 1) { if (argsCount == 1) ls_command(current_directory_info); @@ -727,31 +731,31 @@ int main(void) syscall(5, (uint32_t)too_many_args_msg, 20, 0xF); } - if (commandNumber == 2) + else if (commandNumber == 2) { } - if (commandNumber == 3) + else if (commandNumber == 3) { } - if (commandNumber == 4) + else if (commandNumber == 4) { } - if (commandNumber == 5) + else if (commandNumber == 5) { } - if (commandNumber == 6) + else if (commandNumber == 6) { } - if (commandNumber == 7) + else if (commandNumber == 7) { } - if (commandNumber == 8) + else if (commandNumber == 8) { } } From f4afcb6656107808be715a0d7e3c551e905f9784 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Wed, 26 Apr 2023 20:44:53 +0700 Subject: [PATCH 034/101] fix: delete warnings --- src/user-shell.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index ea8bebe..8112526 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -185,7 +185,7 @@ void set_ParseString(struct ParseString *parse_string, char *str, int size) { * 2 - if file has no name * 3 - if file name or extension is too long */ -int split_filename_extension(const struct ParseString *filename, +int split_filename_extension(struct ParseString *filename, struct ParseString *name, struct ParseString *extension) { @@ -674,9 +674,9 @@ void print_path(uint32_t cluster_number) } void cp_command(struct CurrentDirectoryInfo source_dir, - const struct ParseString *source_name, + struct ParseString *source_name, struct CurrentDirectoryInfo dest_dir, - const struct ParseString *dest_name) { + struct ParseString *dest_name) { // prepare buffer in memory for copying struct ClusterBuffer cl[MAX_FILE_BUFFER_CLUSTER_SIZE]; @@ -689,7 +689,8 @@ void cp_command(struct CurrentDirectoryInfo source_dir, // split source filename to name and extension splitcode = split_filename_extension(source_name, &name, &ext); if(splitcode == 2 || splitcode == 3){ - syscall(5, "Source file not found!\n", 19, 0xF); + char msg[] = "Source file not found!\n"; + syscall(5, (uint32_t) msg, 19, 0xF); return; } @@ -716,7 +717,8 @@ void cp_command(struct CurrentDirectoryInfo source_dir, // split source filename to name and extension splitcode = split_filename_extension(dest_name, &name, &ext); if(splitcode == 2 || splitcode == 3){ - syscall(5, "Source file not found!\n", 19, 0xF); + char msg[] = "Source file not found!\n"; + syscall(5, (uint32_t) msg, 19, 0xF); return; } @@ -743,7 +745,7 @@ void cp_command(struct CurrentDirectoryInfo source_dir, } } -void rm_command(struct CurrentDirectoryInfo file_dir, const struct ParseString *file_name) { +void rm_command(struct CurrentDirectoryInfo file_dir, struct ParseString *file_name) { struct ParseString name; struct ParseString ext; int splitcode; @@ -751,7 +753,8 @@ void rm_command(struct CurrentDirectoryInfo file_dir, const struct ParseString * // split source filename to name and extension splitcode = split_filename_extension(file_name, &name, &ext); if(splitcode == 2 || splitcode == 3){ - syscall(5, "Source file not found!\n", 19, 0xF); + char msg[] = "Source file not found!\n"; + syscall(5, (uint32_t) msg, 19, 0xF); return; } @@ -769,9 +772,9 @@ void rm_command(struct CurrentDirectoryInfo file_dir, const struct ParseString * } void mv_command(struct CurrentDirectoryInfo source_dir, - const struct ParseString *source_name, + struct ParseString *source_name, struct CurrentDirectoryInfo dest_dir, - const struct ParseString *dest_name) { + struct ParseString *dest_name) { cp_command(source_dir, source_name, dest_dir, @@ -780,9 +783,6 @@ void mv_command(struct CurrentDirectoryInfo source_dir, rm_command(source_dir, source_name); } -void recursive_rm_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInfo *info) -{ -} int main(void) { From 008a23941d06fe2062348ce917bb54d33ac90e86 Mon Sep 17 00:00:00 2001 From: Genvictus Date: Wed, 26 Apr 2023 21:23:53 +0700 Subject: [PATCH 035/101] fix: parse-path-for-cd --- src/user-shell.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index 20fac6f..615129a 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -413,7 +413,7 @@ void ls_command(struct CurrentDirectoryInfo info) * * @return - */ -void parse_path_for_cd(struct IndexInfo *indexes, struct IndexInfo *new_path_indexes) +void parse_path_for_cd(char *buf, struct IndexInfo *indexes, struct IndexInfo *new_path_indexes) { reset_indexes(new_path_indexes, INDEXES_MAX_COUNT); // [path_segment_1] [path_segment_2] [path_segment_3] ... @@ -440,7 +440,7 @@ void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory } struct IndexInfo new_path_indexes[INDEXES_MAX_COUNT]; - path_to_cd(indexes, &new_path_indexes); + parse_path_for_cd(buf, indexes, new_path_indexes); int i = 0; int target_buf_length = 6; // "cd " @@ -521,7 +521,7 @@ void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryIn buf[2] = ' '; // t struct IndexInfo new_path_indexes[INDEXES_MAX_COUNT]; - path_to_cd(indexes, &new_path_indexes); + parse_path_for_cd(buf, indexes, new_path_indexes); int i = 0; int target_buf_length = 4; // "cd " From ec83971c1087d4f85ff655a447c9d701a9b27cef Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Thu, 27 Apr 2023 00:46:54 +0700 Subject: [PATCH 036/101] fix: delete packed attribute --- src/user-shell.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index 8112526..036e3ca 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -36,13 +36,13 @@ struct CurrentDirectoryInfo uint32_t current_path_count; uint16_t current_cluster_number; // char current_directory_name[8]; -} __attribute__((packed)); +}; struct IndexInfo { int index; int length; -} __attribute__((packed)); +}; struct IndexInfo defaultIndexInfo = { .index = -1, @@ -53,7 +53,7 @@ struct ParseString { char word[SHELL_BUFFER_SIZE]; int length; -} __attribute__((packed)); +}; void syscall(uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx) { From e9033e64c4055ece4cb8c462d30275f3cc4664bf Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Thu, 27 Apr 2023 01:15:21 +0700 Subject: [PATCH 037/101] fix: cd command --- src/user-shell.c | 194 +++++++++++++++++++++++++---------------------- 1 file changed, 102 insertions(+), 92 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index dce83f3..27dfee6 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -236,133 +236,137 @@ void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf struct IndexInfo param_indexes[INDEXES_MAX_COUNT]; reset_indexes(param_indexes, INDEXES_MAX_COUNT); - if ((uint32_t)indexes != 0) - get_buffer_indexes(buf, param_indexes, '/', indexes->index, indexes->length); - - int i = 0; + bool is_empty_param = (uint32_t)indexes == 0; - if ((uint32_t)indexes != 0 && buf[indexes->index] == '/') + if ((!is_empty_param && buf[indexes->index] == '/') || is_empty_param) { - info->current_cluster_number = ROOT_CLUSTER_NUMBER; - info->current_path_count = 0; + temp_info.current_cluster_number = ROOT_CLUSTER_NUMBER; + temp_info.current_path_count = 0; } - while ((uint32_t)indexes != 0 && i < INDEXES_MAX_COUNT && !is_default_index(param_indexes[i])) + if (!is_empty_param) { + get_buffer_indexes(buf, param_indexes, '/', indexes->index, indexes->length); - if (param_indexes[i].length == 1 && buf[param_indexes[i].index] == '.') - { - i++; - continue; - } + int i = 0; - else if (param_indexes[i].length == 2 && memcmp(buf + param_indexes[i].index, "..", 2) == 0) + while (i < get_words_count(param_indexes)) { - // TODO :go to parent dir - if (temp_info.current_cluster_number != ROOT_CLUSTER_NUMBER) + if (param_indexes[i].length == 1 && buf[param_indexes[i].index] == '.') { - struct ClusterBuffer cl = {0}; + i++; + continue; + } + + else if (param_indexes[i].length == 2 && memcmp(buf + param_indexes[i].index, "..", 2) == 0) + { + // TODO :go to parent dir + + if (temp_info.current_cluster_number != ROOT_CLUSTER_NUMBER) + { + struct ClusterBuffer cl = {0}; + struct FAT32DriverRequest request = { + .buf = &cl, + .name = "\0\0\0\0\0\0\0\0", + .ext = "\0\0\0", + .parent_cluster_number = temp_info.current_cluster_number, + .buffer_size = CLUSTER_SIZE, + }; + + syscall(6, (uint32_t)&request, 0, 0); + + struct FAT32DirectoryTable *dir_table = request.buf; + + temp_info.current_cluster_number = dir_table->table->cluster_low; + temp_info.current_path_count--; + } + } + + else + { + if (param_indexes[i].length > DIRECTORY_NAME_LENGTH) + { + char msg[] = "Directory name is too long: "; + syscall(5, (uint32_t)msg, 29, 0xF); + syscall(5, (uint32_t)buf + param_indexes[i].index, param_indexes[i].length, 0xF); + print_newline(); + + return; + } + struct ClusterBuffer cl[5]; + struct FAT32DriverRequest request = { .buf = &cl, .name = "\0\0\0\0\0\0\0\0", .ext = "\0\0\0", .parent_cluster_number = temp_info.current_cluster_number, - .buffer_size = CLUSTER_SIZE, + .buffer_size = CLUSTER_SIZE * 5, }; syscall(6, (uint32_t)&request, 0, 0); struct FAT32DirectoryTable *dir_table = request.buf; - temp_info.current_cluster_number = dir_table->table->cluster_low; - temp_info.current_path_count--; - } - } - - else - { - if (param_indexes[i].length > DIRECTORY_NAME_LENGTH) - { - char msg[] = "Directory name is too long: "; - syscall(5, (uint32_t)msg, 29, 0xF); - syscall(5, (uint32_t)buf + param_indexes[i].index, param_indexes[i].length, 0xF); - print_newline(); - - return; - } - struct ClusterBuffer cl[5]; - - struct FAT32DriverRequest request = { - .buf = &cl, - .name = "\0\0\0\0\0\0\0\0", - .ext = "\0\0\0", - .parent_cluster_number = temp_info.current_cluster_number, - .buffer_size = CLUSTER_SIZE * 5, - }; + memcpy(request.name, temp_info.paths[temp_info.current_path_count - 1], DIRECTORY_NAME_LENGTH); + request.parent_cluster_number = dir_table->table->cluster_low; - syscall(6, (uint32_t)&request, 0, 0); + int32_t retcode; - struct FAT32DirectoryTable *dir_table = request.buf; + syscall(1, (uint32_t)&request, (uint32_t)&retcode, 0); - memcpy(request.name, temp_info.paths[temp_info.current_path_count - 1], DIRECTORY_NAME_LENGTH); - request.parent_cluster_number = dir_table->table->cluster_low; - - int32_t retcode; + if (retcode != 0) + { + char msg[] = "Failed to read directory: "; + syscall(5, (uint32_t)msg, 27, 0xF); + syscall(5, (uint32_t)request.name, DIRECTORY_NAME_LENGTH, 0xF); + print_newline(); - syscall(1, (uint32_t)&request, (uint32_t)&retcode, 0); + if (retcode == 1) + { + char errorMsg[] = "Error: not a folder\n"; + syscall(5, (uint32_t)errorMsg, 21, 0xF); + } - if (retcode != 0) - { - char msg[] = "Failed to read directory: "; - syscall(5, (uint32_t)msg, 27, 0xF); - syscall(5, (uint32_t)request.name, DIRECTORY_NAME_LENGTH, 0xF); - print_newline(); + else if (retcode == 2) + { + char errorMsg[] = "Error: directory not found\n"; + syscall(5, (uint32_t)errorMsg, 28, 0xF); + } - if (retcode == 1) - { - char errorMsg[] = "Error: not a folder\n"; - syscall(5, (uint32_t)errorMsg, 21, 0xF); + return; } - else if (retcode == 2) - { - char errorMsg[] = "Error: directory not found\n"; - syscall(5, (uint32_t)errorMsg, 21, 0xF); - } + dir_table = request.buf; + uint32_t j = 0; + bool found = FALSE; - return; - } + while (j < dir_table->table->filesize / CLUSTER_SIZE && !found) + { + int k = 0; - dir_table = request.buf; - uint32_t j = 0; - bool found = FALSE; + while (k < dir_table[j].table->n_of_entries && !found) + { + struct FAT32DirectoryEntry *entry = &dir_table[j].table[k]; - while (j < dir_table->table->filesize / CLUSTER_SIZE && !found) - { - int k = 0; + if (memcmp(entry->name, buf + param_indexes[i].index, param_indexes[i].length) == 0 && entry->attribute == ATTR_SUBDIRECTORY) - while (k < dir_table[j].table->n_of_entries && !found) - { - struct FAT32DirectoryEntry *entry = &dir_table[j].table[k]; + { + temp_info.current_cluster_number = entry->cluster_low; + memcpy(temp_info.paths[temp_info.current_path_count], request.name, DIRECTORY_NAME_LENGTH); + temp_info.current_path_count++; + found = TRUE; + } - if (memcmp(entry->name, buf + param_indexes[i].index, param_indexes[i].length) == 0 && entry->attribute == ATTR_SUBDIRECTORY) - - { - temp_info.current_cluster_number = entry->cluster_low; - memcpy(temp_info.paths[temp_info.current_path_count], request.name, DIRECTORY_NAME_LENGTH); - temp_info.current_path_count++; - found = TRUE; + k++; } - k++; + j++; } - - j++; } - } - i++; + i++; + } } copy_directory_info(info, &temp_info); @@ -801,7 +805,7 @@ void mv_command(struct CurrentDirectoryInfo source_dir, int main(void) { - const int DIRECTORY_DISPLAY_OFFSET = 23; + const int DIRECTORY_DISPLAY_OFFSET = 24; char buf[SHELL_BUFFER_SIZE]; struct IndexInfo word_indexes[INDEXES_MAX_COUNT]; @@ -820,15 +824,21 @@ int main(void) reset_buffer(buf, SHELL_BUFFER_SIZE); reset_indexes(word_indexes, INDEXES_MAX_COUNT); - const int DIRECTORY_DISPLAY_LENGTH = DIRECTORY_DISPLAY_OFFSET + current_directory_info.current_path_count * DIRECTORY_NAME_LENGTH + 1; + int DIRECTORY_DISPLAY_LENGTH = DIRECTORY_DISPLAY_OFFSET + (current_directory_info.current_path_count * (DIRECTORY_NAME_LENGTH+1)); + + if (current_directory_info.current_path_count == 0) DIRECTORY_DISPLAY_LENGTH++; char directoryDisplay[DIRECTORY_DISPLAY_LENGTH]; - memcpy(directoryDisplay, "forking-thread-IF2230:", DIRECTORY_DISPLAY_OFFSET); + memcpy(directoryDisplay, "forking-thread-IF2230:/", DIRECTORY_DISPLAY_OFFSET); + + char slash[] = "/"; for (uint32_t i = 0; i < current_directory_info.current_path_count; i++) { - memcpy(directoryDisplay + (i * DIRECTORY_NAME_LENGTH) + DIRECTORY_DISPLAY_OFFSET, current_directory_info.paths[i], DIRECTORY_NAME_LENGTH); + int offset = (i * (DIRECTORY_NAME_LENGTH + 1)) + DIRECTORY_DISPLAY_OFFSET; + if (i > 0) memcpy(directoryDisplay + offset - 1, slash, 1); + memcpy(directoryDisplay + offset, current_directory_info.paths[i], DIRECTORY_NAME_LENGTH); } memcpy(directoryDisplay + DIRECTORY_DISPLAY_LENGTH - 1, "$", 1); From 9eb21ff76f55e3283133c5d4fec3ea10bbb2ff8d Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Thu, 27 Apr 2023 01:22:59 +0700 Subject: [PATCH 038/101] fix: not found msg --- src/user-shell.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index 27dfee6..e326fb4 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -298,7 +298,7 @@ void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf struct FAT32DriverRequest request = { .buf = &cl, - .name = "\0\0\0\0\0\0\0\0", + .name = "\0\0\0\0\0\0\0", .ext = "\0\0\0", .parent_cluster_number = temp_info.current_cluster_number, .buffer_size = CLUSTER_SIZE * 5, @@ -308,7 +308,8 @@ void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf struct FAT32DirectoryTable *dir_table = request.buf; - memcpy(request.name, temp_info.paths[temp_info.current_path_count - 1], DIRECTORY_NAME_LENGTH); + memcpy(request.name, buf + param_indexes[i].index, param_indexes[i].length); + request.parent_cluster_number = dir_table->table->cluster_low; int32_t retcode; From 896a81fcd4fd0cf14d4ff684ae8bc862609e1533 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Thu, 27 Apr 2023 01:41:20 +0700 Subject: [PATCH 039/101] fix: empty command handle --- src/user-shell.c | 91 +++++++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 43 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index e326fb4..52136d0 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -850,68 +850,73 @@ int main(void) get_buffer_indexes(buf, word_indexes, ' ', 0, SHELL_BUFFER_SIZE); - int commandNumber = get_command_number(buf, word_indexes[0].index, word_indexes[0].length); + int argsCount = get_words_count(word_indexes); - if (commandNumber == -1) + if (argsCount > 0) { - char msg[] = "Command not found!\n"; - syscall(5, (uint32_t)msg, 19, 0xF); - } + int commandNumber = get_command_number(buf, word_indexes[0].index, word_indexes[0].length); - else - { - int argsCount = get_words_count(word_indexes); - - if (commandNumber == 0) + if (commandNumber == -1) { - if (argsCount == 1) - cd_command(buf, (uint32_t)0, ¤t_directory_info); - else if (argsCount == 2) - cd_command(buf, word_indexes + 1, ¤t_directory_info); - else - syscall(5, (uint32_t)too_many_args_msg, 20, 0xF); + char msg[] = "Command not found!\n"; + syscall(5, (uint32_t)msg, 19, 0xF); } - else if (commandNumber == 1) + else { - if (argsCount == 1) - ls_command(current_directory_info); - else - syscall(5, (uint32_t)too_many_args_msg, 20, 0xF); - } - else if (commandNumber == 2) - { - } + if (commandNumber == 0) + { + if (argsCount == 1) + cd_command(buf, (uint32_t)0, ¤t_directory_info); + else if (argsCount == 2) + cd_command(buf, word_indexes + 1, ¤t_directory_info); + else + syscall(5, (uint32_t)too_many_args_msg, 20, 0xF); + } - else if (commandNumber == 3) - { - } + else if (commandNumber == 1) + { + if (argsCount == 1) + ls_command(current_directory_info); + else + syscall(5, (uint32_t)too_many_args_msg, 20, 0xF); + } - else if (commandNumber == 4) - { - } + else if (commandNumber == 2) + { + } - else if (commandNumber == 5) - { - } + else if (commandNumber == 3) + { + } - else if (commandNumber == 6) - { - } + else if (commandNumber == 4) + { + } - else if (commandNumber == 7) - { + else if (commandNumber == 5) + { + } + + else if (commandNumber == 6) + { + } + + else if (commandNumber == 7) + { + } + + else if (commandNumber == 8) + { + } } - else if (commandNumber == 8) + if (current_directory_info.current_cluster_number) { } } - if (current_directory_info.current_cluster_number) - { - } } return 0; From 792fd829dc808c594afcd39fe2940cd6b458ee53 Mon Sep 17 00:00:00 2001 From: sozyGithub Date: Thu, 27 Apr 2023 01:59:00 +0700 Subject: [PATCH 040/101] rfc: cd cmd invocation from another cmd --- src/user-shell.c | 134 +++++++++++++++++++++++------------------------ 1 file changed, 66 insertions(+), 68 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index 579bf94..049d2b1 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -413,18 +413,65 @@ void ls_command(struct CurrentDirectoryInfo info) /** * Parse raw path to become useable for cd command * + * @param buf input command buffer * @param indexes initial IndexInfo struct that contains the raw path at index 1 * @param new_path_indexes new path after parsing * * @return - */ -void parse_path_for_cd(char *buf, struct IndexInfo *indexes, struct IndexInfo *new_path_indexes) +void parse_new_path_indexes(char *buf, struct IndexInfo *indexes, struct IndexInfo *new_path_indexes) { reset_indexes(new_path_indexes, INDEXES_MAX_COUNT); // [path_segment_1] [path_segment_2] [path_segment_3] ... get_buffer_indexes(buf, new_path_indexes, '/', indexes[1].index, indexes[1].length); } +/** + * Invoking cd command from another command + * + * @param buf input command buffer + * @param target_buf_length initial target buf length. Example for cat, target_buf_length = length of "cat" + 1 = 4 + * @param new_path_indexes new path after invoking parse_new_path_indexes + * @param indexes initial IndexInfo struct that contains the raw path at index 1 + * @param target_directory new directory info after invoking cd command + * @param target_name parsed target name from buffer + * + * @return - + */ +void invoke_cd(char *buf, + int target_buf_length, + struct IndexInfo *new_path_indexes, + struct IndexInfo *indexes, + struct CurrentDirectoryInfo *target_directory, + char *target_name) +{ + int i = 0; + while (!is_default_index(new_path_indexes[i + 1])) + { + target_buf_length += new_path_indexes[i].length; + i++; + } + + for (int j = target_buf_length; j < target_buf_length + new_path_indexes[i].length; j++) + { + target_name[j - target_buf_length] = buf[j]; + } + + // check if path_segment count > 1 + if (!is_default_index(new_path_indexes[1])) + { + char target_buff[target_buf_length]; + for (int i = 0; i < target_buf_length; i++) + { + target_buff[i] = buf[i]; + } + // call cd command to move the directory + cd_command(target_buff, new_path_indexes, target_directory); + + // TODO: handle failed cd + } +} + /** * Handling mkdir command in shell * @@ -447,46 +494,22 @@ void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory struct IndexInfo new_path_indexes[INDEXES_MAX_COUNT]; parse_path_for_cd(buf, indexes, new_path_indexes); - int i = 0; - int target_buf_length = 6; // "cd " - while (!is_default_index(new_path_indexes[i + 1])) - { - target_buf_length += new_path_indexes[i].length; - i++; - } - - if (new_path_indexes[i].length > 8) + int target_name_length = new_path_indexes[get_words_count(new_path_indexes) - 1].length; + if (target_name_length > 8) { - char msg[] = "Invalid new directory name! Maximum 7 characters!\n"; + char msg[] = "Invalid new directory name! Maximum 8 characters!"; - syscall(5, (uint32_t)msg, 50, 0xF); + syscall(5, (uint32_t)msg, 49, 0xF); + print_newline(); return; } - char new_dir_name[new_path_indexes[i].length]; - for (int j = target_buf_length; j < target_buf_length + new_path_indexes[i].length; j++) - { - new_dir_name[j - target_buf_length] = buf[j]; - } - // temporary CurrentDirectoryInfo for creating the new directory struct CurrentDirectoryInfo target_directory = {}; - copy_directory_info(&target_directory, info); + char target_name[target_name_length]; - // check if path_segment count > 1 - if (!is_default_index(new_path_indexes[1])) - { - char target_buff[target_buf_length]; - for (int i = 0; i < target_buf_length; i++) - { - target_buff[i] = buf[i]; - } - // call cd command to move the directory - cd_command(target_buff, indexes + 1, &target_directory); - - // TODO: handle failed cd - } + invoke_cd(buf, 6, new_path_indexes, indexes, &target_directory, target_name); // create new directory in the target_directory struct ClusterBuffer cl[5]; @@ -497,7 +520,7 @@ void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory .buffer_size = CLUSTER_SIZE * 5, }; - memcpy(write_request.name, new_dir_name, sizeof(new_dir_name)); + memcpy(write_request.name, target_name, target_name_length); int32_t retcode; @@ -528,39 +551,13 @@ void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryIn struct IndexInfo new_path_indexes[INDEXES_MAX_COUNT]; parse_path_for_cd(buf, indexes, new_path_indexes); - int i = 0; - int target_buf_length = 4; // "cd " - while (!is_default_index(new_path_indexes[i + 1])) - { - target_buf_length += new_path_indexes[i].length; - i++; - } - - int target_file_name_length = new_path_indexes[i].length; - char target_file_name[target_file_name_length]; - for (int j = target_buf_length; j < target_buf_length + new_path_indexes[i].length; j++) - { - target_file_name[j - target_buf_length] = buf[j]; - } - // temporary CurrentDirectoryInfo for creating the new directory struct CurrentDirectoryInfo target_directory = {}; - copy_directory_info(&target_directory, info); + int target_name_length = new_path_indexes[get_words_count(new_path_indexes) - 1].length; + char target_name[target_name_length]; - // check if path_segment count > 1 - if (!is_default_index(new_path_indexes[1])) - { - char target_buff[target_buf_length]; - for (int i = 0; i < target_buf_length; i++) - { - target_buff[i] = buf[i]; - } - // call cd command to move the directory - cd_command(target_buff, indexes + 1, &target_directory); - - // TODO: handle failed cd - } + invoke_cd(buf, 6, new_path_indexes, indexes, &target_directory, target_name); // read the file from FATtable struct ClusterBuffer cl[5]; @@ -571,12 +568,12 @@ void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryIn }; struct ParseString target_filename = {}; - set_ParseString(&target_filename, target_file_name, target_file_name_length); + set_ParseString(&target_filename, target_name, target_name_length); struct ParseString target_file_name_parsed = {}; struct ParseString target_file_name_extension = {}; int split_result = split_filename_extension(&target_filename, &target_file_name_parsed, &target_file_name_extension); - memcpy(read_request.name, target_file_name, sizeof(target_file_name)); + memcpy(read_request.name, target_name, target_name_length); if (split_result != 0 && split_result != 1) { syscall(5, (uint32_t) "Invalid command!", 16, 0xF); @@ -825,9 +822,10 @@ int main(void) reset_buffer(buf, SHELL_BUFFER_SIZE); reset_indexes(word_indexes, INDEXES_MAX_COUNT); - int DIRECTORY_DISPLAY_LENGTH = DIRECTORY_DISPLAY_OFFSET + (current_directory_info.current_path_count * (DIRECTORY_NAME_LENGTH+1)); + int DIRECTORY_DISPLAY_LENGTH = DIRECTORY_DISPLAY_OFFSET + (current_directory_info.current_path_count * (DIRECTORY_NAME_LENGTH + 1)); - if (current_directory_info.current_path_count == 0) DIRECTORY_DISPLAY_LENGTH++; + if (current_directory_info.current_path_count == 0) + DIRECTORY_DISPLAY_LENGTH++; char directoryDisplay[DIRECTORY_DISPLAY_LENGTH]; @@ -838,7 +836,8 @@ int main(void) for (uint32_t i = 0; i < current_directory_info.current_path_count; i++) { int offset = (i * (DIRECTORY_NAME_LENGTH + 1)) + DIRECTORY_DISPLAY_OFFSET; - if (i > 0) memcpy(directoryDisplay + offset - 1, slash, 1); + if (i > 0) + memcpy(directoryDisplay + offset - 1, slash, 1); memcpy(directoryDisplay + offset, current_directory_info.paths[i], DIRECTORY_NAME_LENGTH); } @@ -916,7 +915,6 @@ int main(void) { } } - } return 0; From 8e5a0cd76b0e5c90034dfab40a5a71db6c9525a7 Mon Sep 17 00:00:00 2001 From: Genvictus Date: Thu, 27 Apr 2023 13:29:23 +0700 Subject: [PATCH 041/101] rfc: comments and limit definition --- src/user-shell.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index 52136d0..579bf94 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -7,6 +7,7 @@ #define COMMAND_MAX_SIZE 32 #define COMMAND_COUNT 12 #define DIRECTORY_NAME_LENGTH 8 +#define EXTENSION_NAME_LENGTH 3 #define INDEXES_MAX_COUNT SHELL_BUFFER_SIZE #define PATH_MAX_COUNT 256 #define MAX_FILE_BUFFER_CLUSTER_SIZE 512 // take arbitrary size of 512 cluster = 512 * 4 * 512 B = 1MB @@ -174,7 +175,6 @@ void set_ParseString(struct ParseString *parse_string, char *str, int size) /** * Split filename into name and extension * @param filename original filename before split - * @param filename_length length of filename * @param name final filename length after removed of extension * @param extension extension of the file * @return @@ -217,7 +217,7 @@ int split_filename_extension(struct ParseString *filename, // starting from 0 to (last_word_starting_index - 2) is file name int name_length = last_word_starting_index - 1; // therefore (last_word_starting_index - 2) + 1 is length of name - if (name_length > DIRECTORY_NAME_LENGTH || last_word_length > 3) + if (name_length > DIRECTORY_NAME_LENGTH || last_word_length > EXTENSION_NAME_LENGTH) return 3; // copy name memcpy(name->word, filename->word, name_length); From 5182ff8defa0528b82291d2aef22a3c8ac8f0392 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Fri, 28 Apr 2023 00:47:37 +0700 Subject: [PATCH 042/101] fix: reset keyboard buffer --- src/kernel.c | 22 ++++++++++++++++++++++ src/keyboard.c | 6 ++++++ 2 files changed, 28 insertions(+) diff --git a/src/kernel.c b/src/kernel.c index f43a6ef..124e054 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -24,6 +24,28 @@ void kernel_setup(void) { // Allocate first 4 MiB virtual memory allocate_single_user_page_frame((uint8_t*) 0); + // Initiation for testing + struct FAT32DriverRequest req = { + .buf = (uint8_t*) 0, + .name = "f1\0\0\0\0\0\0", + .ext = "\0\0\0", + .parent_cluster_number = ROOT_CLUSTER_NUMBER, + .buffer_size = 0, + }; + write(req); + + memcpy(req.name, "f2", 2); + write(req); + + memcpy(req.name, "f3", 2); + write(req); + + // move parent to f1 + // req.parent_cluster_number = 6; + + // memcpy(req.name, "f4", 2); + // write(req); + // Write shell into memory struct FAT32DriverRequest request = { .buf = (uint8_t*) 0, diff --git a/src/keyboard.c b/src/keyboard.c index e55ddfe..66f2a29 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -34,11 +34,17 @@ static struct KeyboardDriverState keyboard_state = { // Activate keyboard ISR / start listen keyboard & save to buffer void keyboard_state_activate(void){ + for (int i = 0; i < KEYBOARD_BUFFER_SIZE; i++) + { + keyboard_state.keyboard_buffer[i] = '\0'; + } + keyboard_state.keyboard_input_on = TRUE; } // Deactivate keyboard ISR / stop listening keyboard interrupt void keyboard_state_deactivate(void){ + keyboard_state.buffer_index = 0; keyboard_state.keyboard_input_on = FALSE; } From 4157bf1a2c977de10d35b345f53984b8b94294e8 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Fri, 28 Apr 2023 01:17:41 +0700 Subject: [PATCH 043/101] fix: ls command --- src/user-shell.c | 46 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index 579bf94..fe7d53d 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -79,6 +79,12 @@ void print_newline() syscall(5, (uint32_t)newl, 1, 0xF); } +void print_space() +{ + char newl[1] = " "; + syscall(5, (uint32_t)newl, 1, 0xF); +} + void reset_indexes(struct IndexInfo *indexes, uint32_t length) { @@ -298,19 +304,24 @@ void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf struct FAT32DriverRequest request = { .buf = &cl, - .name = "\0\0\0\0\0\0\0", + .name = "root\0\0\0\0", .ext = "\0\0\0", .parent_cluster_number = temp_info.current_cluster_number, .buffer_size = CLUSTER_SIZE * 5, }; - syscall(6, (uint32_t)&request, 0, 0); + struct FAT32DirectoryTable *dir_table; - struct FAT32DirectoryTable *dir_table = request.buf; + if (temp_info.current_path_count > 0) + { + syscall(6, (uint32_t)&request, 0, 0); + + dir_table = request.buf; - memcpy(request.name, buf + param_indexes[i].index, param_indexes[i].length); + memcpy(request.name, buf + param_indexes[i].index, param_indexes[i].length); - request.parent_cluster_number = dir_table->table->cluster_low; + request.parent_cluster_number = dir_table->table->cluster_low; + } int32_t retcode; @@ -378,12 +389,26 @@ void ls_command(struct CurrentDirectoryInfo info) struct ClusterBuffer cl[5]; struct FAT32DriverRequest request = { .buf = &cl, + .name = "root\0\0\0\0", .ext = "\0\0\0", .parent_cluster_number = info.current_cluster_number, .buffer_size = CLUSTER_SIZE * 5, }; - memcpy(request.name, info.paths[info.current_path_count - 1], DIRECTORY_NAME_LENGTH); + if (info.current_path_count > 0) + { + syscall(6, (uint32_t)&request, 0, 0); + + struct FAT32DirectoryTable *dir_table = request.buf; + + request.parent_cluster_number = dir_table->table->cluster_low; + memcpy(request.name, info.paths[info.current_path_count - 1], DIRECTORY_NAME_LENGTH); + } + + else + { + request.parent_cluster_number = ROOT_CLUSTER_NUMBER; + } int32_t retcode; @@ -401,12 +426,19 @@ void ls_command(struct CurrentDirectoryInfo info) int j = 1; while (j < dirTable[i].table->n_of_entries) { - syscall(5, (uint32_t)dirTable[i].table[j].name, DIRECTORY_NAME_LENGTH, 0xF); + uint32_t color; + + if (dirTable[i].table[j].attribute == ATTR_SUBDIRECTORY) color = 0xa; + else color = 0xf; + syscall(5, (uint32_t)dirTable[i].table[j].name, DIRECTORY_NAME_LENGTH, color); + if (j < dirTable[i].table->n_of_entries - 1 || i < dir_table_count - 1) print_space(); j++; } i++; } + + print_newline(); } } From d231e32da5d9a3acc705b645db0dbf7a01a31848 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Fri, 28 Apr 2023 02:02:39 +0700 Subject: [PATCH 044/101] fix: cd_command --- src/kernel.c | 2 +- src/user-shell.c | 43 +++++++++++++++++-------------------------- 2 files changed, 18 insertions(+), 27 deletions(-) diff --git a/src/kernel.c b/src/kernel.c index 124e054..28ae63a 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -41,7 +41,7 @@ void kernel_setup(void) { write(req); // move parent to f1 - // req.parent_cluster_number = 6; + // req.parent_cluster_number = 0x9; // memcpy(req.name, "f4", 2); // write(req); diff --git a/src/user-shell.c b/src/user-shell.c index fe7d53d..d554d9d 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -289,7 +289,7 @@ void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf } } - else + else if (!(temp_info.current_cluster_number == ROOT_CLUSTER_NUMBER && memcmp("root\0\0\0\0", buf + param_indexes[i].index, param_indexes[i].length) == 0)) { if (param_indexes[i].length > DIRECTORY_NAME_LENGTH) { @@ -318,7 +318,7 @@ void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf dir_table = request.buf; - memcpy(request.name, buf + param_indexes[i].index, param_indexes[i].length); + memcpy(request.name, temp_info.paths[temp_info.current_path_count-1], DIRECTORY_NAME_LENGTH); request.parent_cluster_number = dir_table->table->cluster_low; } @@ -327,35 +327,13 @@ void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf syscall(1, (uint32_t)&request, (uint32_t)&retcode, 0); - if (retcode != 0) - { - char msg[] = "Failed to read directory: "; - syscall(5, (uint32_t)msg, 27, 0xF); - syscall(5, (uint32_t)request.name, DIRECTORY_NAME_LENGTH, 0xF); - print_newline(); - - if (retcode == 1) - { - char errorMsg[] = "Error: not a folder\n"; - syscall(5, (uint32_t)errorMsg, 21, 0xF); - } - - else if (retcode == 2) - { - char errorMsg[] = "Error: directory not found\n"; - syscall(5, (uint32_t)errorMsg, 28, 0xF); - } - - return; - } - dir_table = request.buf; uint32_t j = 0; bool found = FALSE; while (j < dir_table->table->filesize / CLUSTER_SIZE && !found) { - int k = 0; + int k = 1; while (k < dir_table[j].table->n_of_entries && !found) { @@ -365,7 +343,7 @@ void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf { temp_info.current_cluster_number = entry->cluster_low; - memcpy(temp_info.paths[temp_info.current_path_count], request.name, DIRECTORY_NAME_LENGTH); + memcpy(temp_info.paths[temp_info.current_path_count], buf + param_indexes[i].index, param_indexes[i].length); temp_info.current_path_count++; found = TRUE; } @@ -375,6 +353,19 @@ void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf j++; } + + if (!found) + { + char msg[] = "Failed to read directory "; + syscall(5, (uint32_t)msg, 26, 0xF); + syscall(5, (uint32_t)buf + param_indexes[i].index, param_indexes[i].length, 0xF); + print_newline(); + + char errorMsg[] = "Error: directory not found\n"; + syscall(5, (uint32_t)errorMsg, 28, 0xF); + + return; + } } i++; From a544933a91e15c06c798dd8ea5939946d2f33ccd Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Fri, 28 Apr 2023 03:10:28 +0700 Subject: [PATCH 045/101] fix: remove warning --- src/user-shell.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index de37754..ee59c01 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -442,13 +442,14 @@ void ls_command(struct CurrentDirectoryInfo info) * * @return - */ -void parse_new_path_indexes(char *buf, struct IndexInfo *indexes, struct IndexInfo *new_path_indexes) +void parse_path_for_cd(char *buf, struct IndexInfo *indexes, struct IndexInfo *new_path_indexes) { reset_indexes(new_path_indexes, INDEXES_MAX_COUNT); // [path_segment_1] [path_segment_2] [path_segment_3] ... get_buffer_indexes(buf, new_path_indexes, '/', indexes[1].index, indexes[1].length); } + /** * Invoking cd command from another command * @@ -464,7 +465,6 @@ void parse_new_path_indexes(char *buf, struct IndexInfo *indexes, struct IndexIn void invoke_cd(char *buf, int target_buf_length, struct IndexInfo *new_path_indexes, - struct IndexInfo *indexes, struct CurrentDirectoryInfo *target_directory, char *target_name) { @@ -532,7 +532,7 @@ void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory copy_directory_info(&target_directory, info); char target_name[target_name_length]; - invoke_cd(buf, 6, new_path_indexes, indexes, &target_directory, target_name); + invoke_cd(buf, 6, new_path_indexes, &target_directory, target_name); // create new directory in the target_directory struct ClusterBuffer cl[5]; @@ -580,7 +580,7 @@ void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryIn int target_name_length = new_path_indexes[get_words_count(new_path_indexes) - 1].length; char target_name[target_name_length]; - invoke_cd(buf, 6, new_path_indexes, indexes, &target_directory, target_name); + invoke_cd(buf, 6, new_path_indexes, &target_directory, target_name); // read the file from FATtable struct ClusterBuffer cl[5]; From 881f2f99b765f9769dbfe4f2ad5398cdd9ceccf5 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Fri, 28 Apr 2023 03:35:16 +0700 Subject: [PATCH 046/101] fix: copy extension for write folder --- src/fat32.c | 1 + src/kernel.c | 19 ++++++++++++++++--- src/user-shell.c | 11 +++++++---- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/fat32.c b/src/fat32.c index fdcd2b2..1da0111 100644 --- a/src/fat32.c +++ b/src/fat32.c @@ -552,6 +552,7 @@ void create_subdirectory_from_entry(uint32_t cluster_number, // Increment the number of entry in its targeted parent's directory table increment_subdir_n_of_entry(&(driver_state.dir_table_buf)); memcpy(entry->name, req.name, 8); + memcpy(entry->ext, req.ext, 3); entry->filesize = req.buffer_size; entry->cluster_high = (uint16_t)cluster_number >> 16; entry->cluster_low = (uint16_t)cluster_number & 0x0000FFFF; diff --git a/src/kernel.c b/src/kernel.c index 28ae63a..ec5b0f8 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -41,10 +41,23 @@ void kernel_setup(void) { write(req); // move parent to f1 - // req.parent_cluster_number = 0x9; + req.parent_cluster_number = 0x9; - // memcpy(req.name, "f4", 2); - // write(req); + memcpy(req.name, "f4", 2); + write(req); + + memcpy(req.name, "f5", 2); + write(req); + + // move parent to f1 + req.parent_cluster_number = 0xc; + + memcpy(req.name, "f6", 2); + write(req); + + req.parent_cluster_number = 0xe; + memcpy(req.name, "f7", 2); + write(req); // Write shell into memory struct FAT32DriverRequest request = { diff --git a/src/user-shell.c b/src/user-shell.c index ee59c01..89a29af 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -396,10 +396,6 @@ void ls_command(struct CurrentDirectoryInfo info) memcpy(request.name, info.paths[info.current_path_count - 1], DIRECTORY_NAME_LENGTH); } - else - { - request.parent_cluster_number = ROOT_CLUSTER_NUMBER; - } int32_t retcode; @@ -431,6 +427,13 @@ void ls_command(struct CurrentDirectoryInfo info) print_newline(); } + + else + { + char msg[] = "Failed to read current directory\n"; + syscall(5, (uint32_t)msg, 34, 0xF); + + } } /** From 57c094c0844c426e07d9a1b474809c9de7e90e1e Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Fri, 28 Apr 2023 03:52:14 +0700 Subject: [PATCH 047/101] fix: directory search condition --- src/fat32.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/fat32.c b/src/fat32.c index 1da0111..6c1a65b 100644 --- a/src/fat32.c +++ b/src/fat32.c @@ -204,7 +204,7 @@ int8_t read_directory(struct FAT32DriverRequest request) { entry = &(driver_state.dir_table_buf.table[i]); found_matching_file = - !is_entry_empty(entry) && is_dir_name_same(entry, request); + !is_entry_empty(entry) && is_dir_name_same(entry, request) && memcmp(entry->ext, "\0\0\0", 3) == 0; found_matching_directory = found_matching_file && is_subdirectory(entry); } @@ -552,7 +552,7 @@ void create_subdirectory_from_entry(uint32_t cluster_number, // Increment the number of entry in its targeted parent's directory table increment_subdir_n_of_entry(&(driver_state.dir_table_buf)); memcpy(entry->name, req.name, 8); - memcpy(entry->ext, req.ext, 3); + memcpy(entry->ext, "\0\0\0", 3); entry->filesize = req.buffer_size; entry->cluster_high = (uint16_t)cluster_number >> 16; entry->cluster_low = (uint16_t)cluster_number & 0x0000FFFF; @@ -785,6 +785,8 @@ uint32_t get_n_of_cluster_subdir(struct FAT32DirectoryEntry *entry) { bool is_requested_directory_already_exist(struct FAT32DriverRequest req) { read_clusters(&driver_state.dir_table_buf, req.parent_cluster_number, 1); + // Determine whether we're creating a file or a folder + bool is_creating_directory = req.buffer_size == 0; // Iterate through the directory entries and find the same folder/file. Return // early if file with the same name already exist. @@ -804,7 +806,8 @@ bool is_requested_directory_already_exist(struct FAT32DriverRequest req) { // Check if it's similar - same_entry = is_dir_ext_name_same(entry, req); + if(is_creating_directory) same_entry = is_dir_name_same(entry, req) && memcmp(entry->ext, "\0\0\0", 3) == 0; + else same_entry = is_dir_ext_name_same(entry, req); if (same_entry) { return TRUE; From 97506ec45abcb12de47e42abd02dbed229b05aae Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Fri, 28 Apr 2023 05:14:52 +0700 Subject: [PATCH 048/101] feat: add path parameter in ls command --- src/user-shell.c | 58 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index 89a29af..cab884b 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -9,7 +9,7 @@ #define DIRECTORY_NAME_LENGTH 8 #define EXTENSION_NAME_LENGTH 3 #define INDEXES_MAX_COUNT SHELL_BUFFER_SIZE -#define PATH_MAX_COUNT 256 +#define PATH_MAX_COUNT 64 #define MAX_FILE_BUFFER_CLUSTER_SIZE 512 // take arbitrary size of 512 cluster = 512 * 4 * 512 B = 1MB #define EMPTY_EXTENSION "\0\0\0" @@ -234,8 +234,10 @@ int split_filename_extension(struct ParseString *filename, return 0; } -void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInfo *info) +uint8_t cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInfo *info) { + // return 0 if fail, 1 if succeed + struct CurrentDirectoryInfo temp_info = {}; copy_directory_info(&temp_info, info); @@ -298,7 +300,7 @@ void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf syscall(5, (uint32_t)buf + param_indexes[i].index, param_indexes[i].length, 0xF); print_newline(); - return; + return 0; } struct ClusterBuffer cl[5]; @@ -339,11 +341,22 @@ void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf { struct FAT32DirectoryEntry *entry = &dir_table[j].table[k]; - if (memcmp(entry->name, buf + param_indexes[i].index, param_indexes[i].length) == 0 && entry->attribute == ATTR_SUBDIRECTORY) + char name[DIRECTORY_NAME_LENGTH] = "\0\0\0\0\0\0\0\0"; + + memcpy(name, buf + param_indexes[i].index, param_indexes[i].length); + + if (memcmp(entry->name, name, DIRECTORY_NAME_LENGTH) == 0 && entry->attribute == ATTR_SUBDIRECTORY) { + if (temp_info.current_path_count == PATH_MAX_COUNT - 1) + { + char msg[] = "cd command reaches maximum depth\n"; + syscall(5, (uint32_t)msg, 34, 0xF); + return 0; + } + temp_info.current_cluster_number = entry->cluster_low; - memcpy(temp_info.paths[temp_info.current_path_count], buf + param_indexes[i].index, param_indexes[i].length); + memcpy(temp_info.paths[temp_info.current_path_count], name, DIRECTORY_NAME_LENGTH); temp_info.current_path_count++; found = TRUE; } @@ -364,7 +377,7 @@ void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf char errorMsg[] = "Error: directory not found\n"; syscall(5, (uint32_t)errorMsg, 28, 0xF); - return; + return 0; } } @@ -373,27 +386,36 @@ void cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf } copy_directory_info(info, &temp_info); + return 1; } -void ls_command(struct CurrentDirectoryInfo info) +void ls_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInfo info) { + struct CurrentDirectoryInfo temp_info = {}; + copy_directory_info(&temp_info, &info); + + if ((uint32_t) indexes != 0) { + int status = cd_command(buf, indexes, &temp_info); + if (!status) return; + } + struct ClusterBuffer cl[5]; struct FAT32DriverRequest request = { .buf = &cl, .name = "root\0\0\0\0", .ext = "\0\0\0", - .parent_cluster_number = info.current_cluster_number, + .parent_cluster_number = temp_info.current_cluster_number, .buffer_size = CLUSTER_SIZE * 5, }; - if (info.current_path_count > 0) + if (temp_info.current_path_count > 0) { syscall(6, (uint32_t)&request, 0, 0); struct FAT32DirectoryTable *dir_table = request.buf; request.parent_cluster_number = dir_table->table->cluster_low; - memcpy(request.name, info.paths[info.current_path_count - 1], DIRECTORY_NAME_LENGTH); + memcpy(request.name, temp_info.paths[temp_info.current_path_count - 1], DIRECTORY_NAME_LENGTH); } @@ -430,8 +452,10 @@ void ls_command(struct CurrentDirectoryInfo info) else { - char msg[] = "Failed to read current directory\n"; - syscall(5, (uint32_t)msg, 34, 0xF); + char msg[] = "Failed to read directory "; + syscall(5, (uint32_t)msg, 26, 0xF); + syscall(5, (uint32_t)request.name, DIRECTORY_NAME_LENGTH, 0xF); + print_newline(); } } @@ -893,9 +917,14 @@ int main(void) if (commandNumber == 0) { if (argsCount == 1) + { cd_command(buf, (uint32_t)0, ¤t_directory_info); + } else if (argsCount == 2) + { cd_command(buf, word_indexes + 1, ¤t_directory_info); + } + else syscall(5, (uint32_t)too_many_args_msg, 20, 0xF); } @@ -903,7 +932,10 @@ int main(void) else if (commandNumber == 1) { if (argsCount == 1) - ls_command(current_directory_info); + ls_command(buf, (uint32_t) 0, current_directory_info); + + else if (argsCount == 2) + ls_command(buf, word_indexes + 1, current_directory_info); else syscall(5, (uint32_t)too_many_args_msg, 20, 0xF); } From 3726e18022b39554af8962af02a22376913e3464 Mon Sep 17 00:00:00 2001 From: Genvictus Date: Fri, 28 Apr 2023 13:35:16 +0700 Subject: [PATCH 049/101] rfc: invoke_cd parameter data type for reusability --- src/user-shell.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index cab884b..c7df0cf 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -493,7 +493,7 @@ void invoke_cd(char *buf, int target_buf_length, struct IndexInfo *new_path_indexes, struct CurrentDirectoryInfo *target_directory, - char *target_name) + struct ParseString *target_name) { int i = 0; while (!is_default_index(new_path_indexes[i + 1])) @@ -504,8 +504,9 @@ void invoke_cd(char *buf, for (int j = target_buf_length; j < target_buf_length + new_path_indexes[i].length; j++) { - target_name[j - target_buf_length] = buf[j]; + target_name->word[j - target_buf_length] = buf[j]; } + target_name->length = new_path_indexes[i].length; // check if path_segment count > 1 if (!is_default_index(new_path_indexes[1])) From 59b717a51520f39bb0438ae17dc923fef4cb1e50 Mon Sep 17 00:00:00 2001 From: Genvictus Date: Fri, 28 Apr 2023 13:35:52 +0700 Subject: [PATCH 050/101] feat: link cp, rm, mv command to main shell program --- src/user-shell.c | 67 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 9 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index c7df0cf..3459d92 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -483,7 +483,6 @@ void parse_path_for_cd(char *buf, struct IndexInfo *indexes, struct IndexInfo *n * @param buf input command buffer * @param target_buf_length initial target buf length. Example for cat, target_buf_length = length of "cat" + 1 = 4 * @param new_path_indexes new path after invoking parse_new_path_indexes - * @param indexes initial IndexInfo struct that contains the raw path at index 1 * @param target_directory new directory info after invoking cd command * @param target_name parsed target name from buffer * @@ -736,9 +735,9 @@ void print_path(uint32_t cluster_number) } } -void cp_command(struct CurrentDirectoryInfo source_dir, +void cp_command(struct CurrentDirectoryInfo *source_dir, struct ParseString *source_name, - struct CurrentDirectoryInfo dest_dir, + struct CurrentDirectoryInfo *dest_dir, struct ParseString *dest_name) { // prepare buffer in memory for copying @@ -764,7 +763,7 @@ void cp_command(struct CurrentDirectoryInfo source_dir, .buf = &cl, // .name = EMPTY_NAME, .ext = EMPTY_EXTENSION, - .parent_cluster_number = source_dir.current_cluster_number, + .parent_cluster_number = source_dir->current_cluster_number, .buffer_size = CLUSTER_SIZE * MAX_FILE_BUFFER_CLUSTER_SIZE, }; memcpy(read_request.name, name.word, name.length); @@ -793,7 +792,7 @@ void cp_command(struct CurrentDirectoryInfo source_dir, .buf = &cl, // .name = EMPTY_NAME, .ext = EMPTY_EXTENSION, - .parent_cluster_number = dest_dir.current_cluster_number, + .parent_cluster_number = dest_dir->current_cluster_number, .buffer_size = CLUSTER_SIZE * MAX_FILE_BUFFER_CLUSTER_SIZE, }; memcpy(write_request.name, name.word, name.length); @@ -811,7 +810,7 @@ void cp_command(struct CurrentDirectoryInfo source_dir, } } -void rm_command(struct CurrentDirectoryInfo file_dir, struct ParseString *file_name) +void rm_command(struct CurrentDirectoryInfo *file_dir, struct ParseString *file_name) { struct ParseString name; struct ParseString ext; @@ -830,7 +829,7 @@ void rm_command(struct CurrentDirectoryInfo file_dir, struct ParseString *file_n struct FAT32DriverRequest delete_request = { // .name = EMPTY_NAME, .ext = EMPTY_EXTENSION, - .parent_cluster_number = file_dir.current_cluster_number, + .parent_cluster_number = file_dir->current_cluster_number, }; memcpy(delete_request.name, name.word, name.length); memcpy(delete_request.ext, ext.word, ext.length); @@ -839,9 +838,9 @@ void rm_command(struct CurrentDirectoryInfo file_dir, struct ParseString *file_n syscall(3, (uint32_t)&delete_request, (uint32_t)&retcode, 0); } -void mv_command(struct CurrentDirectoryInfo source_dir, +void mv_command(struct CurrentDirectoryInfo *source_dir, struct ParseString *source_name, - struct CurrentDirectoryInfo dest_dir, + struct CurrentDirectoryInfo *dest_dir, struct ParseString *dest_name) { cp_command(source_dir, @@ -951,14 +950,64 @@ int main(void) else if (commandNumber == 4) { + // cp_command + struct CurrentDirectoryInfo source_dir = current_directory_info; + struct CurrentDirectoryInfo dest_dir = current_directory_info; + + struct ParseString source_name; + struct ParseString dest_name; + + // get source directory info & source file name + struct IndexInfo new_path_indexes[INDEXES_MAX_COUNT]; + parse_path_for_cd(buf, word_indexes, new_path_indexes); + invoke_cd(buf, word_indexes[1].index, new_path_indexes, &source_dir, &source_name); + + // get destination directory info & source file name + reset_indexes(new_path_indexes, INDEXES_MAX_COUNT); + parse_path_for_cd(buf, word_indexes+1, new_path_indexes); + invoke_cd(buf, word_indexes[2].index, new_path_indexes, &dest_dir, &dest_name); + + // invoke cp command + cp_command(&source_dir, &source_name, &dest_dir, &dest_name); } else if (commandNumber == 5) { + // rm_command + struct CurrentDirectoryInfo target_dir = current_directory_info; + + struct ParseString target_name; + + // get source directory info & source file name + struct IndexInfo new_path_indexes[INDEXES_MAX_COUNT]; + parse_path_for_cd(buf, word_indexes, new_path_indexes); + invoke_cd(buf, word_indexes[1].index, new_path_indexes, &target_dir, &target_name); + + // invoke cp command + rm_command(&target_dir, &target_name); } else if (commandNumber == 6) { + // mv_command + struct CurrentDirectoryInfo source_dir = current_directory_info; + struct CurrentDirectoryInfo dest_dir = current_directory_info; + + struct ParseString source_name; + struct ParseString dest_name; + + // get source directory info & source file name + struct IndexInfo new_path_indexes[INDEXES_MAX_COUNT]; + parse_path_for_cd(buf, word_indexes, new_path_indexes); + invoke_cd(buf, word_indexes[1].index, new_path_indexes, &source_dir, &source_name); + + // get destination directory info & source file name + reset_indexes(new_path_indexes, INDEXES_MAX_COUNT); + parse_path_for_cd(buf, word_indexes+1, new_path_indexes); + invoke_cd(buf, word_indexes[2].index, new_path_indexes, &dest_dir, &dest_name); + + // invoke cp command + mv_command(&source_dir, &source_name, &dest_dir, &dest_name); } else if (commandNumber == 7) From a10cd60e76cdbc4c029345f7a74d62680b1b043d Mon Sep 17 00:00:00 2001 From: Fatih20 Date: Fri, 28 Apr 2023 21:55:46 +0700 Subject: [PATCH 051/101] Retrofitting recursive deletion. --- src/fat32.c | 307 +++++++++++++++++++++++++++-------------- src/interrupt.c | 3 +- src/lib-header/fat32.h | 6 +- src/user-shell.c | 59 +++++--- 4 files changed, 245 insertions(+), 130 deletions(-) diff --git a/src/fat32.c b/src/fat32.c index 6c1a65b..843babc 100644 --- a/src/fat32.c +++ b/src/fat32.c @@ -90,11 +90,13 @@ const uint8_t fs_signature[BLOCK_SIZE] = { static struct FAT32DriverState driver_state; static char empty_cluster_value[CLUSTER_SIZE]; -uint32_t cluster_to_lba(uint32_t cluster) { +uint32_t cluster_to_lba(uint32_t cluster) +{ return cluster * CLUSTER_BLOCK_COUNT + BOOT_SECTOR; } -void create_fat32(void) { +void create_fat32(void) +{ // Copy fs_signature write_blocks(fs_signature, BOOT_SECTOR, 1); @@ -104,7 +106,8 @@ void create_fat32(void) { driver_state.fat_table.cluster_map[2] = FAT32_FAT_END_OF_FILE; // Empty the remaining entry in the fat table - for (int i = 3; i < CLUSTER_MAP_SIZE; i++) { + for (int i = 3; i < CLUSTER_MAP_SIZE; i++) + { driver_state.fat_table.cluster_map[i] = 0; } write_clusters(&driver_state.fat_table, 1, 1); @@ -115,8 +118,10 @@ void create_fat32(void) { write_clusters(&root, 2, 1); } -void initialize_filesystem_fat32(void) { - if (is_empty_storage()) { +void initialize_filesystem_fat32(void) +{ + if (is_empty_storage()) + { // Create FAT if it's empty create_fat32(); } @@ -125,32 +130,37 @@ void initialize_filesystem_fat32(void) { read_clusters(&driver_state.fat_table, 1, 1); // Initialize static array for empty clusters - for (int i = 0; i < CLUSTER_SIZE; i++) { + for (int i = 0; i < CLUSTER_SIZE; i++) + { empty_cluster_value[i] = 0; } } -bool is_empty_storage() { +bool is_empty_storage() +{ uint8_t boot_sector[BLOCK_SIZE]; read_blocks(&boot_sector, BOOT_SECTOR, 1); return memcmp(boot_sector, fs_signature, BLOCK_SIZE); } void write_clusters(const void *ptr, uint32_t cluster_number, - uint8_t cluster_count) { + uint8_t cluster_count) +{ uint32_t logical_block_address = cluster_to_lba(cluster_number); uint8_t block_count = cluster_count * CLUSTER_BLOCK_COUNT; write_blocks(ptr, logical_block_address, block_count); } -void read_clusters(void *ptr, uint32_t cluster_number, uint8_t cluster_count) { +void read_clusters(void *ptr, uint32_t cluster_number, uint8_t cluster_count) +{ uint32_t logical_block_address = cluster_to_lba(cluster_number); uint8_t block_count = cluster_count * CLUSTER_BLOCK_COUNT; read_blocks(ptr, logical_block_address, block_count); } void init_directory_table(struct FAT32DirectoryTable *dir_table, char *name, - uint32_t parent_dir_cluster) { + uint32_t parent_dir_cluster) +{ memcpy(dir_table->table[0].name, name, 8); dir_table->table[0].cluster_high = parent_dir_cluster >> 16; dir_table->table[0].cluster_low = parent_dir_cluster & 0xFFFF; @@ -160,19 +170,22 @@ void init_directory_table(struct FAT32DirectoryTable *dir_table, char *name, } void init_directory_table_child(struct FAT32DirectoryTable *dir_table, - char *name, uint32_t parent_dir_cluster) { + char *name, uint32_t parent_dir_cluster) +{ init_directory_table(dir_table, name, parent_dir_cluster); dir_table->table[0].attribute = ATTR_SUBDIRECTORY_CHILD; } -int8_t read_directory(struct FAT32DriverRequest request) { +int8_t read_directory(struct FAT32DriverRequest request) +{ read_clusters(&driver_state.dir_table_buf, request.parent_cluster_number, 1); if (request.parent_cluster_number == ROOT_CLUSTER_NUMBER && memcmp("root\0\0\0\0", request.name, 8) == 0) { // Return error when the buffer size is insufficient - if (request.buffer_size < driver_state.dir_table_buf.table->filesize) { + if (request.buffer_size < driver_state.dir_table_buf.table->filesize) + { return -1; } @@ -182,7 +195,8 @@ int8_t read_directory(struct FAT32DriverRequest request) { } // If given parent cluster number isn't the head of a directory, return error - if (is_dirtable_child(&driver_state.dir_table_buf)) { + if (is_dirtable_child(&driver_state.dir_table_buf)) + { return 3; } @@ -194,13 +208,15 @@ int8_t read_directory(struct FAT32DriverRequest request) { bool end_of_directory = FALSE; uint16_t now_cluster_number = request.parent_cluster_number; - while (!end_of_directory && !found_matching_directory) { + while (!end_of_directory && !found_matching_directory) + { // Traverse the table in examined cluster. Starts from 1 because the first // entry of the table is the directory itself for (uint8_t i = 1; i < CLUSTER_SIZE / sizeof(struct FAT32DirectoryEntry) && !found_matching_directory; - i++) { + i++) + { entry = &(driver_state.dir_table_buf.table[i]); found_matching_file = @@ -218,7 +234,8 @@ int8_t read_directory(struct FAT32DriverRequest request) { continue; // Move onto the next cluster if it's not the end yet - if (!end_of_directory) { + if (!end_of_directory) + { now_cluster_number = driver_state.fat_table.cluster_map[now_cluster_number]; read_clusters(&driver_state.dir_table_buf, (uint32_t)now_cluster_number, @@ -227,16 +244,19 @@ int8_t read_directory(struct FAT32DriverRequest request) { } // Return error when entry is not a folder - if (!found_matching_directory && found_matching_file) { + if (!found_matching_directory && found_matching_file) + { return 1; } - if (!found_matching_directory) { + if (!found_matching_directory) + { return 2; } // Return error when the buffer size is insufficient - if (request.buffer_size < entry->filesize) { + if (request.buffer_size < entry->filesize) + { return -1; } @@ -245,12 +265,14 @@ int8_t read_directory(struct FAT32DriverRequest request) { return 0; } -int8_t read(struct FAT32DriverRequest request) { +int8_t read(struct FAT32DriverRequest request) +{ read_clusters(&driver_state.dir_table_buf, request.parent_cluster_number, 1); read_clusters(&driver_state.fat_table, 1, 1); // If given parent cluster number isn't the head of a directory, return error - if (!is_parent_cluster_valid(request)) { + if (!is_parent_cluster_valid(request)) + { return 4; } @@ -261,13 +283,15 @@ int8_t read(struct FAT32DriverRequest request) { bool end_of_directory = FALSE; uint16_t now_cluster_number = request.parent_cluster_number; - while (!end_of_directory && !found_matching_file) { + while (!end_of_directory && !found_matching_file) + { // Traverse the table in examined cluster. Starts from 1 because the first // entry of the table is the directory itself for (uint8_t i = 0; i < CLUSTER_SIZE / sizeof(struct FAT32DirectoryEntry) && !found_matching_file; - i++) { + i++) + { entry = &(driver_state.dir_table_buf.table[i]); found_matching_file = @@ -284,7 +308,8 @@ int8_t read(struct FAT32DriverRequest request) { continue; // Move onto the next cluster if it's not the end yet - if (!end_of_directory) { + if (!end_of_directory) + { now_cluster_number = driver_state.fat_table.cluster_map[now_cluster_number]; read_clusters(&driver_state.dir_table_buf, (uint32_t)now_cluster_number, @@ -294,17 +319,20 @@ int8_t read(struct FAT32DriverRequest request) { // Check if the entry isn't empty and matches the requested name and // attributes. If it's not satisfied, skip. - if (!found_matching_file) { + if (!found_matching_file) + { return 3; } // Return error when entry is a folder - if (is_subdirectory(entry)) { + if (is_subdirectory(entry)) + { return 1; } // Return error when not enough buffer size - if (request.buffer_size < entry->filesize) { + if (request.buffer_size < entry->filesize) + { return 2; } @@ -314,7 +342,8 @@ int8_t read(struct FAT32DriverRequest request) { return 0; } -int8_t write(struct FAT32DriverRequest request) { +int8_t write(struct FAT32DriverRequest request) +{ read_clusters(&driver_state.dir_table_buf, request.parent_cluster_number, 1); read_clusters(&driver_state.fat_table, 1, 1); @@ -327,7 +356,8 @@ int8_t write(struct FAT32DriverRequest request) { // Determine whether we're creating a file or a folder bool is_creating_directory = request.buffer_size == 0; - if (is_requested_directory_already_exist(request)) { + if (is_requested_directory_already_exist(request)) + { return 1; } @@ -343,11 +373,13 @@ int8_t write(struct FAT32DriverRequest request) { uint32_t last_occupied_cluster_number; // Iterate through the directory entries and find empty cluster - for (int i = 3; i < CLUSTER_MAP_SIZE && !check_empty; i++) { + for (int i = 3; i < CLUSTER_MAP_SIZE && !check_empty; i++) + { // Check if the cluster empty, if yes target the cluster check_empty = driver_state.fat_table.cluster_map[i] == (uint32_t)0; - if (check_empty) { + if (check_empty) + { if (count == 0) new_cluster_number = i; count++; @@ -357,7 +389,8 @@ int8_t write(struct FAT32DriverRequest request) { } // If not enough clusters to create the requested directory, return erro - if (!check_empty) { + if (!check_empty) + { return -1; } @@ -369,7 +402,8 @@ int8_t write(struct FAT32DriverRequest request) { bool end_of_directory = FALSE; struct FAT32DirectoryEntry *entry; - while (!end_of_directory && !found_empty_entry) { + while (!end_of_directory && !found_empty_entry) + { // Skip checking the cluster if it's known that it's full cluster_full = is_subdirectory_cluster_full(&(driver_state.dir_table_buf)); @@ -377,7 +411,8 @@ int8_t write(struct FAT32DriverRequest request) { for (uint8_t i = 1; (i < CLUSTER_SIZE / sizeof(struct FAT32DirectoryEntry)) && !found_empty_entry && !cluster_full; - i++) { + i++) + { entry = &(driver_state.dir_table_buf.table[i]); @@ -398,7 +433,8 @@ int8_t write(struct FAT32DriverRequest request) { 0xFFFF) == 0xFFFF; // Move onto the next cluster if it's not the end yet - if (!end_of_directory) { + if (!end_of_directory) + { now_cluster_number = driver_state.fat_table.cluster_map[now_cluster_number]; read_clusters(&driver_state.dir_table_buf, (uint32_t)now_cluster_number, @@ -408,13 +444,15 @@ int8_t write(struct FAT32DriverRequest request) { // If there are no empty directories, create new cluster from the requested // parent cluster - if (!found_empty_entry) { + if (!found_empty_entry) + { // Create the child cluster of the target directory. dir_table_buf will be // set into the table of the child cluster bool succesfully_created_child_cluster = create_child_cluster_of_subdir( last_occupied_cluster_number, prev_cluster_number, &request); - if (!succesfully_created_child_cluster) { + if (!succesfully_created_child_cluster) + { return -1; } @@ -423,16 +461,19 @@ int8_t write(struct FAT32DriverRequest request) { entry = &(driver_state.dir_table_buf.table[1]); } - else { + else + { request.parent_cluster_number = now_cluster_number; } - //set_create_datetime(entry); + // set_create_datetime(entry); // Create a directory - if (is_creating_directory) { + if (is_creating_directory) + { - if (memcmp("root\0\0\0\0", request.name, 8) == 0) return 3; + if (memcmp("root\0\0\0\0", request.name, 8) == 0) + return 3; create_subdirectory_from_entry(new_cluster_number, entry, request); return 0; @@ -443,11 +484,13 @@ int8_t write(struct FAT32DriverRequest request) { return 0; } -int8_t delete(struct FAT32DriverRequest request) { +int8_t delete(struct FAT32DriverRequest request, bool is_recursive) +{ read_clusters(&driver_state.dir_table_buf, request.parent_cluster_number, 1); // If given parent cluster number isn't the head of a directory, return error - if (!is_parent_cluster_valid(request)) { + if (!is_parent_cluster_valid(request)) + { return 4; } @@ -459,16 +502,20 @@ int8_t delete(struct FAT32DriverRequest request) { uint16_t now_cluster_number = request.parent_cluster_number; uint16_t prev_cluster_number; - while (!end_of_directory && !found_directory) { + while (!end_of_directory && !found_directory) + { for (uint8_t i = 1; i < CLUSTER_SIZE / sizeof(struct FAT32DirectoryEntry) && !found_directory; - i++) { + i++) + { entry = &(driver_state.dir_table_buf.table[i]); - if (!is_entry_empty(entry)) { - found_directory = is_dir_ext_name_same(entry, request); - } + if (!is_entry_empty(entry)) + { + found_directory = is_dir_ext_name_same(entry, request); + } - else { + else + { found_directory = FALSE; } } @@ -487,7 +534,8 @@ int8_t delete(struct FAT32DriverRequest request) { continue; // Move onto the next cluster if it's not the end yet - if (!end_of_directory) { + if (!end_of_directory) + { now_cluster_number = driver_state.fat_table.cluster_map[now_cluster_number]; read_clusters(&driver_state.dir_table_buf, (uint32_t)now_cluster_number, @@ -496,15 +544,18 @@ int8_t delete(struct FAT32DriverRequest request) { } // Failed to find any matching directory - if (!found_directory) { + if (!found_directory) + { return 1; } request.parent_cluster_number = prev_cluster_number; // Found a matching directory entry, check if subdirectory empty or not - if (is_subdirectory(entry)) { - if (!is_subdirectory_immediately_empty(entry)) { + if (is_subdirectory(entry)) + { + if (!is_subdirectory_immediately_empty(entry)) + { return 2; } @@ -519,26 +570,31 @@ int8_t delete(struct FAT32DriverRequest request) { return 0; } -bool is_entry_empty(struct FAT32DirectoryEntry *entry) { +bool is_entry_empty(struct FAT32DirectoryEntry *entry) +{ return entry->user_attribute != UATTR_NOT_EMPTY; } bool is_dir_name_same(struct FAT32DirectoryEntry *entry, - struct FAT32DriverRequest req) { + struct FAT32DriverRequest req) +{ return memcmp(entry->name, req.name, 8) == 0; }; bool is_dir_ext_same(struct FAT32DirectoryEntry *entry, - struct FAT32DriverRequest req) { + struct FAT32DriverRequest req) +{ return memcmp(entry->ext, req.ext, 3) == 0; }; bool is_dir_ext_name_same(struct FAT32DirectoryEntry *entry, - struct FAT32DriverRequest req) { + struct FAT32DriverRequest req) +{ return is_dir_name_same(entry, req) && is_dir_ext_same(entry, req); }; -bool is_subdirectory(struct FAT32DirectoryEntry *entry) { +bool is_subdirectory(struct FAT32DirectoryEntry *entry) +{ return entry->attribute == ATTR_SUBDIRECTORY; }; @@ -546,7 +602,8 @@ int ceil(int a, int b) { return (a / b) + ((a % b != 0) ? 1 : 0); } void create_subdirectory_from_entry(uint32_t cluster_number, struct FAT32DirectoryEntry *entry, - struct FAT32DriverRequest req) { + struct FAT32DriverRequest req) +{ driver_state.fat_table.cluster_map[cluster_number] = FAT32_FAT_END_OF_FILE; // Increment the number of entry in its targeted parent's directory table @@ -573,7 +630,8 @@ void create_subdirectory_from_entry(uint32_t cluster_number, void create_file_from_entry(uint32_t cluster_number, struct FAT32DirectoryEntry *entry, - struct FAT32DriverRequest req) { + struct FAT32DriverRequest req) +{ // Increment the number of entry in its targeted parent's directory table increment_subdir_n_of_entry(&(driver_state.dir_table_buf)); entry->cluster_high = cluster_number >> 16; @@ -582,12 +640,15 @@ void create_file_from_entry(uint32_t cluster_number, int required_clusters = ceil(req.buffer_size, CLUSTER_SIZE); uint32_t old_cluster_number; - for (int i = 0; i < required_clusters; i++) { + for (int i = 0; i < required_clusters; i++) + { write_clusters(req.buf + CLUSTER_SIZE * i, cluster_number, 1); old_cluster_number = cluster_number; - for (int j = old_cluster_number + 1; j < CLUSTER_MAP_SIZE; j++) { + for (int j = old_cluster_number + 1; j < CLUSTER_MAP_SIZE; j++) + { // Check if the cluster is empty - if (driver_state.fat_table.cluster_map[j] == 0) { + if (driver_state.fat_table.cluster_map[j] == 0) + { cluster_number = j; break; } @@ -607,11 +668,13 @@ void create_file_from_entry(uint32_t cluster_number, write_clusters(&driver_state.dir_table_buf, req.parent_cluster_number, 1); }; -bool is_subdirectory_immediately_empty(struct FAT32DirectoryEntry *entry) { +bool is_subdirectory_immediately_empty(struct FAT32DirectoryEntry *entry) +{ uint16_t now_cluster_number = entry->cluster_low; struct FAT32DirectoryTable subdir_table; bool found_filled = FALSE; - do { + do + { read_clusters(&subdir_table, now_cluster_number, 1); now_cluster_number = driver_state.fat_table.cluster_map[now_cluster_number] & 0xFFFF; @@ -636,16 +699,19 @@ bool is_subdirectory_immediately_empty(struct FAT32DirectoryEntry *entry) { // return TRUE; // }; -void reset_cluster(uint32_t cluster_number) { +void reset_cluster(uint32_t cluster_number) +{ write_clusters(empty_cluster_value, cluster_number, 1); } void delete_subdirectory_by_entry(struct FAT32DirectoryEntry *entry, - struct FAT32DriverRequest req) { + struct FAT32DriverRequest req) +{ uint16_t now_cluster_number = entry->cluster_low; uint16_t next_cluster_number; - do { + do + { next_cluster_number = (uint16_t)(driver_state.fat_table.cluster_map[now_cluster_number] & 0xFFFF); @@ -669,10 +735,12 @@ void delete_subdirectory_by_entry(struct FAT32DirectoryEntry *entry, } void delete_file_by_entry(struct FAT32DirectoryEntry *entry, - struct FAT32DriverRequest req) { + struct FAT32DriverRequest req) +{ uint16_t now_cluster_number = entry->cluster_low; uint16_t next_cluster_number; - do { + do + { next_cluster_number = (uint16_t)(driver_state.fat_table.cluster_map[now_cluster_number] & 0xFFFF); @@ -695,64 +763,76 @@ void delete_file_by_entry(struct FAT32DirectoryEntry *entry, } void read_directory_by_entry(struct FAT32DirectoryEntry *entry, - struct FAT32DriverRequest req) { + struct FAT32DriverRequest req) +{ uint16_t now_cluster_number = entry->cluster_low; uint8_t nth_cluster = 0; - do { + do + { read_clusters(req.buf + CLUSTER_SIZE * nth_cluster, now_cluster_number, 1); now_cluster_number = driver_state.fat_table.cluster_map[now_cluster_number] & 0x0000FFFF; nth_cluster++; } while (now_cluster_number != 0xFFFF); - //set_access_datetime(entry); + // set_access_datetime(entry); } void read_directory_by_cluster_number(uint16_t cluster_number, - struct FAT32DriverRequest req) { + struct FAT32DriverRequest req) +{ uint16_t now_cluster_number = cluster_number; uint8_t nth_cluster = 0; - do { + do + { read_clusters(req.buf + CLUSTER_SIZE * nth_cluster, now_cluster_number, 1); now_cluster_number = driver_state.fat_table.cluster_map[now_cluster_number] & 0x0000FFFF; nth_cluster++; } while (now_cluster_number != 0xFFFF); - //set_access_datetime(entry); + // set_access_datetime(entry); } -void increment_subdir_n_of_entry(struct FAT32DirectoryTable *table) { +void increment_subdir_n_of_entry(struct FAT32DirectoryTable *table) +{ table->table[0].n_of_entries++; } -uint32_t get_subdir_n_of_entry(struct FAT32DirectoryTable *table) { +uint32_t get_subdir_n_of_entry(struct FAT32DirectoryTable *table) +{ return table->table[0].n_of_entries; }; -void decrement_subdir_n_of_entry(struct FAT32DirectoryTable *table) { +void decrement_subdir_n_of_entry(struct FAT32DirectoryTable *table) +{ table->table[0].n_of_entries--; } -bool is_subdirectory_cluster_full(struct FAT32DirectoryTable *subdir) { +bool is_subdirectory_cluster_full(struct FAT32DirectoryTable *subdir) +{ return subdir->table[0].n_of_entries >= (CLUSTER_SIZE / sizeof(struct FAT32DirectoryEntry)); } -bool is_parent_cluster_valid(struct FAT32DriverRequest request) { +bool is_parent_cluster_valid(struct FAT32DriverRequest request) +{ struct FAT32DirectoryTable current_parent_table; read_clusters(¤t_parent_table, request.parent_cluster_number, 1); - if (current_parent_table.table[0].cluster_low == ROOT_CLUSTER_NUMBER) { + if (current_parent_table.table[0].cluster_low == ROOT_CLUSTER_NUMBER) + { return TRUE; } - if (is_dirtable_child(&driver_state.dir_table_buf) || current_parent_table.table[0].attribute != ATTR_SUBDIRECTORY) { + if (is_dirtable_child(&driver_state.dir_table_buf) || current_parent_table.table[0].attribute != ATTR_SUBDIRECTORY) + { return FALSE; } uint32_t target_cluster_number = request.parent_cluster_number; int8_t visited_parent[CLUSTER_MAP_SIZE]; - for (uint32_t i = 0; i < CLUSTER_MAP_SIZE; i++) { + for (uint32_t i = 0; i < CLUSTER_MAP_SIZE; i++) + { visited_parent[i] = 0; } @@ -760,7 +840,8 @@ bool is_parent_cluster_valid(struct FAT32DriverRequest request) { while (target_cluster_number < CLUSTER_MAP_SIZE && target_cluster_number > ROOT_CLUSTER_NUMBER && - visited_parent[target_cluster_number] == 0) { + visited_parent[target_cluster_number] == 0) + { visited_parent[target_cluster_number] = 1; read_clusters(¤t_parent_table, target_cluster_number, 1); @@ -771,18 +852,22 @@ bool is_parent_cluster_valid(struct FAT32DriverRequest request) { return target_cluster_number == ROOT_CLUSTER_NUMBER; } -bool is_subdirectory_cluster_empty(struct FAT32DirectoryTable *subdir) { +bool is_subdirectory_cluster_empty(struct FAT32DirectoryTable *subdir) +{ return subdir->table[0].n_of_entries == 1; }; -bool is_dirtable_child(struct FAT32DirectoryTable *subdir) { +bool is_dirtable_child(struct FAT32DirectoryTable *subdir) +{ return subdir->table[0].attribute == ATTR_SUBDIRECTORY_CHILD; }; -uint32_t get_n_of_cluster_subdir(struct FAT32DirectoryEntry *entry) { +uint32_t get_n_of_cluster_subdir(struct FAT32DirectoryEntry *entry) +{ return entry->filesize / CLUSTER_SIZE; }; -bool is_requested_directory_already_exist(struct FAT32DriverRequest req) { +bool is_requested_directory_already_exist(struct FAT32DriverRequest req) +{ read_clusters(&driver_state.dir_table_buf, req.parent_cluster_number, 1); // Determine whether we're creating a file or a folder @@ -793,10 +878,12 @@ bool is_requested_directory_already_exist(struct FAT32DriverRequest req) { bool same_entry = FALSE; uint16_t now_cluster_number = req.parent_cluster_number; bool end_of_directory = FALSE; - while (!end_of_directory && !same_entry) { + while (!end_of_directory && !same_entry) + { for (uint8_t i = 1; i < CLUSTER_SIZE / sizeof(struct FAT32DirectoryEntry); - i++) { + i++) + { struct FAT32DirectoryEntry *entry = &(driver_state.dir_table_buf.table[i]); @@ -806,10 +893,13 @@ bool is_requested_directory_already_exist(struct FAT32DriverRequest req) { // Check if it's similar - if(is_creating_directory) same_entry = is_dir_name_same(entry, req) && memcmp(entry->ext, "\0\0\0", 3) == 0; - else same_entry = is_dir_ext_name_same(entry, req); - - if (same_entry) { + if (is_creating_directory) + same_entry = is_dir_name_same(entry, req) && memcmp(entry->ext, "\0\0\0", 3) == 0; + else + same_entry = is_dir_ext_name_same(entry, req); + + if (same_entry) + { return TRUE; } } @@ -820,7 +910,8 @@ bool is_requested_directory_already_exist(struct FAT32DriverRequest req) { 0x0000FFFF) == 0xFFFF; // Move onto the next cluster if it's not the end yet - if (!end_of_directory) { + if (!end_of_directory) + { now_cluster_number = driver_state.fat_table.cluster_map[now_cluster_number]; read_clusters(&driver_state.dir_table_buf, (uint32_t)now_cluster_number, @@ -836,7 +927,8 @@ bool is_requested_directory_already_exist(struct FAT32DriverRequest req) { bool create_child_cluster_of_subdir(uint32_t last_occupied_cluster_number, uint16_t prev_cluster_number, - struct FAT32DriverRequest *req) { + struct FAT32DriverRequest *req) +{ // Iterate through the file allocation table and find empty cluster for the // directory expansion uint32_t new_cluster_number_directory; @@ -844,7 +936,8 @@ bool create_child_cluster_of_subdir(uint32_t last_occupied_cluster_number, // Find clusters after the allocated cluster of the requested directory itself for (int i = last_occupied_cluster_number + 1; - i < CLUSTER_MAP_SIZE && !empty_cluster_found; i++) { + i < CLUSTER_MAP_SIZE && !empty_cluster_found; i++) + { // Check if the cluster is empty, if yes target the cluster empty_cluster_found = driver_state.fat_table.cluster_map[i] == (uint32_t)0; @@ -853,7 +946,8 @@ bool create_child_cluster_of_subdir(uint32_t last_occupied_cluster_number, } // If not enough cluster for expanding directory, return error - if (!empty_cluster_found) { + if (!empty_cluster_found) + { return FALSE; } @@ -884,18 +978,21 @@ bool create_child_cluster_of_subdir(uint32_t last_occupied_cluster_number, return TRUE; }; -void set_create_datetime(struct FAT32DirectoryEntry *entry) { +void set_create_datetime(struct FAT32DirectoryEntry *entry) +{ uint32_t FTTimestamp = get_FTTimestamp_time(); entry->create_date = ((FTTimestamp & 0xFFFF0000) >> 16); entry->create_time = (FTTimestamp & 0x0000FFFF); } -void set_modified_date(struct FAT32DirectoryEntry *entry) { +void set_modified_date(struct FAT32DirectoryEntry *entry) +{ uint32_t FTTimestamp = get_FTTimestamp_time(); entry->modified_date = ((FTTimestamp & 0xFFFF0000) >> 16); } -void set_access_datetime(struct FAT32DirectoryEntry *entry) { +void set_access_datetime(struct FAT32DirectoryEntry *entry) +{ uint32_t FTTimestamp = get_FTTimestamp_time(); entry->access_date = ((FTTimestamp & 0xFFFF0000) >> 16); entry->access_time = (FTTimestamp & 0x0000FFFF); @@ -915,7 +1012,7 @@ void set_access_datetime(struct FAT32DirectoryEntry *entry) { // while (i < count) // { // bool found_matching_directory = FALSE; -// bool end_of_directory = FALSE; +// bool end_of_directory = FALSE; // uint16_t temp_cluster_number = current_cluster_number; // while (!end_of_directory && !found_matching_directory) { @@ -950,7 +1047,7 @@ void set_access_datetime(struct FAT32DirectoryEntry *entry) { // i++; // current_cluster_number = entry->cluster_low; // } - + // return current_cluster_number; // } diff --git a/src/interrupt.c b/src/interrupt.c index 48a99c0..2ad582c 100644 --- a/src/interrupt.c +++ b/src/interrupt.c @@ -149,7 +149,8 @@ void syscall(struct CPURegister cpu, __attribute__((unused)) struct InterruptSta else if (cpu.eax == 3) { struct FAT32DriverRequest request = *(struct FAT32DriverRequest *)cpu.ebx; - *((int8_t *)cpu.ecx) = delete(request); + bool is_recursive = (bool)cpu.edx; + *((int8_t *)cpu.ecx) = delete (request, is_recursive); } else if (cpu.eax == 4) diff --git a/src/lib-header/fat32.h b/src/lib-header/fat32.h index c9372f6..ca4f945 100644 --- a/src/lib-header/fat32.h +++ b/src/lib-header/fat32.h @@ -267,10 +267,12 @@ int8_t write(struct FAT32DriverRequest request); * file system. * * @param request buf and buffer_size is unused + * @param whether deletion should be recursive. Value only affects subdirectory deletion and doesn't affect file * @return Error code: 0 success - 1 not found - 2 folder is not empty - -1 * unknown - 4 invalid parent cluster + * - 5 folder structure too deep for recursion */ -int8_t delete(struct FAT32DriverRequest request); +int8_t delete(struct FAT32DriverRequest request, bool is_recursive); /* -- Getter/Setter Auxiliary Function -- */ @@ -448,7 +450,7 @@ void read_directory_by_entry(struct FAT32DirectoryEntry *entry, * @param req The request to which read result is to be transferred */ void read_directory_by_cluster_number(uint16_t cluster_number, - struct FAT32DriverRequest req); + struct FAT32DriverRequest req); /** * @brief Create a child cluster of a subdirectory diff --git a/src/user-shell.c b/src/user-shell.c index 3459d92..247bc6f 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -24,8 +24,8 @@ const char command_list[COMMAND_COUNT][COMMAND_MAX_SIZE] = { "rm\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "mv\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "whereis\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + "rm -r\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + "cp -r\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", }; @@ -320,7 +320,7 @@ uint8_t cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory dir_table = request.buf; - memcpy(request.name, temp_info.paths[temp_info.current_path_count-1], DIRECTORY_NAME_LENGTH); + memcpy(request.name, temp_info.paths[temp_info.current_path_count - 1], DIRECTORY_NAME_LENGTH); request.parent_cluster_number = dir_table->table->cluster_low; } @@ -376,7 +376,7 @@ uint8_t cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory char errorMsg[] = "Error: directory not found\n"; syscall(5, (uint32_t)errorMsg, 28, 0xF); - + return 0; } } @@ -394,9 +394,11 @@ void ls_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf struct CurrentDirectoryInfo temp_info = {}; copy_directory_info(&temp_info, &info); - if ((uint32_t) indexes != 0) { + if ((uint32_t)indexes != 0) + { int status = cd_command(buf, indexes, &temp_info); - if (!status) return; + if (!status) + return; } struct ClusterBuffer cl[5]; @@ -418,7 +420,6 @@ void ls_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf memcpy(request.name, temp_info.paths[temp_info.current_path_count - 1], DIRECTORY_NAME_LENGTH); } - int32_t retcode; syscall(1, (uint32_t)&request, (uint32_t)&retcode, 0); @@ -437,16 +438,19 @@ void ls_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf { uint32_t color; - if (dirTable[i].table[j].attribute == ATTR_SUBDIRECTORY) color = 0xa; - else color = 0xf; + if (dirTable[i].table[j].attribute == ATTR_SUBDIRECTORY) + color = 0xa; + else + color = 0xf; syscall(5, (uint32_t)dirTable[i].table[j].name, DIRECTORY_NAME_LENGTH, color); - if (j < dirTable[i].table->n_of_entries - 1 || i < dir_table_count - 1) print_space(); + if (j < dirTable[i].table->n_of_entries - 1 || i < dir_table_count - 1) + print_space(); j++; } i++; } - + print_newline(); } @@ -456,7 +460,6 @@ void ls_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf syscall(5, (uint32_t)msg, 26, 0xF); syscall(5, (uint32_t)request.name, DIRECTORY_NAME_LENGTH, 0xF); print_newline(); - } } @@ -476,7 +479,6 @@ void parse_path_for_cd(char *buf, struct IndexInfo *indexes, struct IndexInfo *n get_buffer_indexes(buf, new_path_indexes, '/', indexes[1].index, indexes[1].length); } - /** * Invoking cd command from another command * @@ -810,7 +812,7 @@ void cp_command(struct CurrentDirectoryInfo *source_dir, } } -void rm_command(struct CurrentDirectoryInfo *file_dir, struct ParseString *file_name) +void rm_command(struct CurrentDirectoryInfo *file_dir, struct ParseString *file_name, bool is_recursive) { struct ParseString name; struct ParseString ext; @@ -835,7 +837,7 @@ void rm_command(struct CurrentDirectoryInfo *file_dir, struct ParseString *file_ memcpy(delete_request.ext, ext.word, ext.length); int32_t retcode; - syscall(3, (uint32_t)&delete_request, (uint32_t)&retcode, 0); + syscall(3, (uint32_t)&delete_request, (uint32_t)&retcode, is_recursive); } void mv_command(struct CurrentDirectoryInfo *source_dir, @@ -848,7 +850,7 @@ void mv_command(struct CurrentDirectoryInfo *source_dir, dest_dir, dest_name); - rm_command(source_dir, source_name); + rm_command(source_dir, source_name, FALSE); } int main(void) @@ -919,7 +921,7 @@ int main(void) if (argsCount == 1) { cd_command(buf, (uint32_t)0, ¤t_directory_info); - } + } else if (argsCount == 2) { cd_command(buf, word_indexes + 1, ¤t_directory_info); @@ -932,8 +934,8 @@ int main(void) else if (commandNumber == 1) { if (argsCount == 1) - ls_command(buf, (uint32_t) 0, current_directory_info); - + ls_command(buf, (uint32_t)0, current_directory_info); + else if (argsCount == 2) ls_command(buf, word_indexes + 1, current_directory_info); else @@ -964,7 +966,7 @@ int main(void) // get destination directory info & source file name reset_indexes(new_path_indexes, INDEXES_MAX_COUNT); - parse_path_for_cd(buf, word_indexes+1, new_path_indexes); + parse_path_for_cd(buf, word_indexes + 1, new_path_indexes); invoke_cd(buf, word_indexes[2].index, new_path_indexes, &dest_dir, &dest_name); // invoke cp command @@ -984,7 +986,7 @@ int main(void) invoke_cd(buf, word_indexes[1].index, new_path_indexes, &target_dir, &target_name); // invoke cp command - rm_command(&target_dir, &target_name); + rm_command(&target_dir, &target_name, FALSE); } else if (commandNumber == 6) @@ -1003,7 +1005,7 @@ int main(void) // get destination directory info & source file name reset_indexes(new_path_indexes, INDEXES_MAX_COUNT); - parse_path_for_cd(buf, word_indexes+1, new_path_indexes); + parse_path_for_cd(buf, word_indexes + 1, new_path_indexes); invoke_cd(buf, word_indexes[2].index, new_path_indexes, &dest_dir, &dest_name); // invoke cp command @@ -1012,10 +1014,23 @@ int main(void) else if (commandNumber == 7) { + // rm recursive command + struct CurrentDirectoryInfo target_dir = current_directory_info; + + struct ParseString target_name; + + // get source directory info & source file name + struct IndexInfo new_path_indexes[INDEXES_MAX_COUNT]; + parse_path_for_cd(buf, word_indexes, new_path_indexes); + invoke_cd(buf, word_indexes[1].index, new_path_indexes, &target_dir, &target_name); + + // invoke rm recursive command + rm_command(&target_dir, &target_name, TRUE); } else if (commandNumber == 8) { + // cp recursive command } } From edf332678bd1a7c092dea9d76326cdd2cdd90066 Mon Sep 17 00:00:00 2001 From: Fatih20 Date: Fri, 28 Apr 2023 22:44:57 +0700 Subject: [PATCH 052/101] Impement checker function of recursion depth. --- src/fat32.c | 62 ++++++++++++++++++++++++++++++++++++++++-- src/interrupt.c | 2 +- src/lib-header/fat32.h | 18 ++++++++++-- 3 files changed, 77 insertions(+), 5 deletions(-) diff --git a/src/fat32.c b/src/fat32.c index 843babc..e44f81f 100644 --- a/src/fat32.c +++ b/src/fat32.c @@ -484,7 +484,7 @@ int8_t write(struct FAT32DriverRequest request) return 0; } -int8_t delete(struct FAT32DriverRequest request, bool is_recursive) +int8_t delete(struct FAT32DriverRequest request, bool is_recursive, bool check_recursion) { read_clusters(&driver_state.dir_table_buf, request.parent_cluster_number, 1); @@ -554,11 +554,15 @@ int8_t delete(struct FAT32DriverRequest request, bool is_recursive) // Found a matching directory entry, check if subdirectory empty or not if (is_subdirectory(entry)) { - if (!is_subdirectory_immediately_empty(entry)) + + // Exit if the deletion is not recursive but the directory is not empty + if (!is_subdirectory_immediately_empty(entry) && !is_recursive) { return 2; } + read_clusters(&driver_state.dir_table_buf, request.parent_cluster_number, 1); + // Folder is empty and can be deleted delete_subdirectory_by_entry(entry, request); @@ -998,6 +1002,60 @@ void set_access_datetime(struct FAT32DirectoryEntry *entry) entry->access_time = (FTTimestamp & 0x0000FFFF); } +bool is_below_max_recursion_depth(uint16_t target_cluster_number, uint8_t recursion_count) +{ + // Basis + if (recursion_count >= MAX_RECURSIVE_OP_DEPTH) + { + return FALSE; + } + + // Get the directory table of the directory to check + read_clusters(&driver_state.dir_table_buf, target_cluster_number, 1); + + bool end_of_directory = FALSE; + struct FAT32DirectoryEntry *entry; + + uint16_t now_cluster_number = target_cluster_number; + uint16_t prev_cluster_number; + + while (!end_of_directory) + { + for (uint8_t i = 1; i < CLUSTER_SIZE / sizeof(struct FAT32DirectoryEntry); + i++) + { + entry = &(driver_state.dir_table_buf.table[i]); + if (is_subdirectory(entry)) + { + // Return false if recursive checking finds the subdirectory in the directory too deep + if (!is_below_max_recursion_depth(entry->cluster_low, recursion_count + 1)) + { + return FALSE; + } + } + } + + // If the cluster_number is EOF, then we've finished examining the last + // cluster of the directory + end_of_directory = (driver_state.fat_table.cluster_map[now_cluster_number] & + 0x0000FFFF) == 0xFFFF; + + // Take notes of the latest_cluster_number for the proper copying of + // directory table + prev_cluster_number = now_cluster_number; + + // Move onto the next cluster if it's not the end yet + if (!end_of_directory) + { + now_cluster_number = + driver_state.fat_table.cluster_map[now_cluster_number]; + read_clusters(&driver_state.dir_table_buf, (uint32_t)now_cluster_number, + 1); + } + } + return TRUE; +} + // uint32_t read_cluster_number(char** directories, int count, uint16_t latest_parent_cluster_number) { // // return ROOT_CLUSTER_NUMBER if not found diff --git a/src/interrupt.c b/src/interrupt.c index 2ad582c..db6929c 100644 --- a/src/interrupt.c +++ b/src/interrupt.c @@ -150,7 +150,7 @@ void syscall(struct CPURegister cpu, __attribute__((unused)) struct InterruptSta { struct FAT32DriverRequest request = *(struct FAT32DriverRequest *)cpu.ebx; bool is_recursive = (bool)cpu.edx; - *((int8_t *)cpu.ecx) = delete (request, is_recursive); + *((int8_t *)cpu.ecx) = delete (request, is_recursive, TRUE); } else if (cpu.eax == 4) diff --git a/src/lib-header/fat32.h b/src/lib-header/fat32.h index ca4f945..e02a459 100644 --- a/src/lib-header/fat32.h +++ b/src/lib-header/fat32.h @@ -34,6 +34,9 @@ #define ATTR_SUBDIRECTORY_CHILD 0b00010001 #define UATTR_NOT_EMPTY 0b10101010 +/* -- File operation constant -- */ +#define MAX_RECURSIVE_OP_DEPTH 64 + // Boot sector signature for this file system "FAT32 - IF2230 edition" extern const uint8_t fs_signature[BLOCK_SIZE]; @@ -267,12 +270,13 @@ int8_t write(struct FAT32DriverRequest request); * file system. * * @param request buf and buffer_size is unused - * @param whether deletion should be recursive. Value only affects subdirectory deletion and doesn't affect file + * @param is_recursive whether deletion should be recursive. Value only affects subdirectory deletion and doesn't affect file + * @param check_recursion whether the given directory have been checked to be shallow enough for recursion * @return Error code: 0 success - 1 not found - 2 folder is not empty - -1 * unknown - 4 invalid parent cluster * - 5 folder structure too deep for recursion */ -int8_t delete(struct FAT32DriverRequest request, bool is_recursive); +int8_t delete(struct FAT32DriverRequest request, bool is_recursive, bool check_recursion); /* -- Getter/Setter Auxiliary Function -- */ @@ -483,4 +487,14 @@ void set_modified_date(struct FAT32DirectoryEntry *entry); */ void set_access_datetime(struct FAT32DirectoryEntry *entry); +/** + * @brief Check whether the depth of the directory is deeper than the MAX_RECURSIVE_OP_DEPTH + * + * @param lower_cluster_number the cluster number of the directory to be checked + * @param recursion_count the number of recursion so far + * @return true + * @return false + */ +bool is_below_max_recursion_depth(uint16_t target_cluster_number, uint8_t recursion_count); + #endif From efb904a37f00e5fb931ee9719806f0b6fcee943a Mon Sep 17 00:00:00 2001 From: Fatih20 Date: Fri, 28 Apr 2023 23:02:26 +0700 Subject: [PATCH 053/101] Implement is_below_max_recursion_depth into delete. --- src/fat32.c | 36 +++++++++++++++++++++++------------- src/lib-header/fat32.h | 2 +- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/fat32.c b/src/fat32.c index e44f81f..df61a35 100644 --- a/src/fat32.c +++ b/src/fat32.c @@ -551,26 +551,36 @@ int8_t delete(struct FAT32DriverRequest request, bool is_recursive, bool check_r request.parent_cluster_number = prev_cluster_number; - // Found a matching directory entry, check if subdirectory empty or not - if (is_subdirectory(entry)) + if (!is_subdirectory(entry)) { + // Not a folder, delete as a file + delete_file_by_entry(entry, request); + return 0; + } - // Exit if the deletion is not recursive but the directory is not empty - if (!is_subdirectory_immediately_empty(entry) && !is_recursive) - { - return 2; - } - - read_clusters(&driver_state.dir_table_buf, request.parent_cluster_number, 1); + // Exit if the deletion is not recursive but the directory is not empty + if (!is_subdirectory_immediately_empty(entry) && !is_recursive) + { + return 2; + } - // Folder is empty and can be deleted + // Folder is empty and can be deleted + if (is_subdirectory_immediately_empty(entry) && !is_recursive) + { delete_subdirectory_by_entry(entry, request); - return 0; } - // Not a folder, delete as a file - delete_file_by_entry(entry, request); + // If check recursion is false, no checking will be done + if (check_recursion && !is_below_max_recursion_depth(entry->cluster_low, 0)) + { + return 5; + } + + // Reset the read clusters to the initial state of the function + read_clusters(&driver_state.dir_table_buf, request.parent_cluster_number, 1); + // Start recursive deletion + return 0; } diff --git a/src/lib-header/fat32.h b/src/lib-header/fat32.h index e02a459..4706689 100644 --- a/src/lib-header/fat32.h +++ b/src/lib-header/fat32.h @@ -271,7 +271,7 @@ int8_t write(struct FAT32DriverRequest request); * * @param request buf and buffer_size is unused * @param is_recursive whether deletion should be recursive. Value only affects subdirectory deletion and doesn't affect file - * @param check_recursion whether the given directory have been checked to be shallow enough for recursion + * @param check_recursion whether the given directory have been checked to be shallow enough for recursion. Should be TRUE during initial call * @return Error code: 0 success - 1 not found - 2 folder is not empty - -1 * unknown - 4 invalid parent cluster * - 5 folder structure too deep for recursion From c37fd17e85346690e60d1b1af843169bbfb3e699 Mon Sep 17 00:00:00 2001 From: Genvictus Date: Sat, 29 Apr 2023 00:10:36 +0700 Subject: [PATCH 054/101] fix: invoke_cd word processing --- src/user-shell.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index 3459d92..9b588cd 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -481,7 +481,6 @@ void parse_path_for_cd(char *buf, struct IndexInfo *indexes, struct IndexInfo *n * Invoking cd command from another command * * @param buf input command buffer - * @param target_buf_length initial target buf length. Example for cat, target_buf_length = length of "cat" + 1 = 4 * @param new_path_indexes new path after invoking parse_new_path_indexes * @param target_directory new directory info after invoking cd command * @param target_name parsed target name from buffer @@ -489,29 +488,24 @@ void parse_path_for_cd(char *buf, struct IndexInfo *indexes, struct IndexInfo *n * @return - */ void invoke_cd(char *buf, - int target_buf_length, struct IndexInfo *new_path_indexes, struct CurrentDirectoryInfo *target_directory, struct ParseString *target_name) { - int i = 0; - while (!is_default_index(new_path_indexes[i + 1])) - { - target_buf_length += new_path_indexes[i].length; - i++; - } + int last_word_index = get_words_count(new_path_indexes) - 1; + int last_word_starting_index = new_path_indexes[last_word_index].index; - for (int j = target_buf_length; j < target_buf_length + new_path_indexes[i].length; j++) + for (int j = last_word_starting_index; j < last_word_starting_index + new_path_indexes[last_word_index].length; j++) { - target_name->word[j - target_buf_length] = buf[j]; + target_name->word[j - last_word_starting_index] = buf[j]; } - target_name->length = new_path_indexes[i].length; + target_name->length = new_path_indexes[last_word_index].length; // check if path_segment count > 1 if (!is_default_index(new_path_indexes[1])) { - char target_buff[target_buf_length]; - for (int i = 0; i < target_buf_length; i++) + char target_buff[last_word_starting_index-1]; + for (int i = 0; i < last_word_starting_index-1; i++) { target_buff[i] = buf[i]; } From fc0596c6ada783205f0ff96fc44bbb698909f482 Mon Sep 17 00:00:00 2001 From: Genvictus Date: Sat, 29 Apr 2023 00:20:39 +0700 Subject: [PATCH 055/101] fix: invoke_cd word processing logic error --- src/user-shell.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/user-shell.c b/src/user-shell.c index 9b588cd..1c4315f 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -482,6 +482,7 @@ void parse_path_for_cd(char *buf, struct IndexInfo *indexes, struct IndexInfo *n * * @param buf input command buffer * @param new_path_indexes new path after invoking parse_new_path_indexes + * @param last_word_starting_index initial target buf length. Example for cat, target_buf_length = length of "cat" + 1 = 4 * @param target_directory new directory info after invoking cd command * @param target_name parsed target name from buffer * @@ -489,11 +490,12 @@ void parse_path_for_cd(char *buf, struct IndexInfo *indexes, struct IndexInfo *n */ void invoke_cd(char *buf, struct IndexInfo *new_path_indexes, + int last_word_starting_index, struct CurrentDirectoryInfo *target_directory, struct ParseString *target_name) { int last_word_index = get_words_count(new_path_indexes) - 1; - int last_word_starting_index = new_path_indexes[last_word_index].index; + last_word_starting_index += new_path_indexes[last_word_index].index; for (int j = last_word_starting_index; j < last_word_starting_index + new_path_indexes[last_word_index].length; j++) { From bde6a9586c56a0b8f075484575fd5bde52c4d27c Mon Sep 17 00:00:00 2001 From: Genvictus Date: Sat, 29 Apr 2023 00:45:03 +0700 Subject: [PATCH 056/101] rfc: doxygen formatting --- src/user-shell.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index 1c4315f..6220aeb 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -172,6 +172,12 @@ void copy_directory_info(struct CurrentDirectoryInfo *dest, struct CurrentDirect memcpy(dest->paths, source->paths, PATH_MAX_COUNT * DIRECTORY_NAME_LENGTH); } +/** + * Set char buffer of ParseString data struct with input string with certain size + * @param parse_string ParseString data to be filled with input string + * @param str the string to be copied into parse_string + * @param size the size of string to be copied into parse_string +*/ void set_ParseString(struct ParseString *parse_string, char *str, int size) { memcpy(parse_string->word, str, size); @@ -480,22 +486,22 @@ void parse_path_for_cd(char *buf, struct IndexInfo *indexes, struct IndexInfo *n /** * Invoking cd command from another command * - * @param buf input command buffer - * @param new_path_indexes new path after invoking parse_new_path_indexes - * @param last_word_starting_index initial target buf length. Example for cat, target_buf_length = length of "cat" + 1 = 4 - * @param target_directory new directory info after invoking cd command - * @param target_name parsed target name from buffer + * @param buf input command buffer + * @param new_path_indexes new path after invoking parse_new_path_indexes + * @param target_starting_index target starting index in buffer. Example for "cat f1/test.txt" -> starting index of "f1/test.txt" = 4 + * @param target_directory new directory info after invoking cd command + * @param target_name parsed target name from buffer * * @return - */ void invoke_cd(char *buf, struct IndexInfo *new_path_indexes, - int last_word_starting_index, + int target_starting_index, struct CurrentDirectoryInfo *target_directory, struct ParseString *target_name) { int last_word_index = get_words_count(new_path_indexes) - 1; - last_word_starting_index += new_path_indexes[last_word_index].index; + int last_word_starting_index = target_starting_index + new_path_indexes[last_word_index].index; for (int j = last_word_starting_index; j < last_word_starting_index + new_path_indexes[last_word_index].length; j++) { From 95a002d6e22b62f819b35b947200e59bfd492da5 Mon Sep 17 00:00:00 2001 From: sozyGithub Date: Sat, 29 Apr 2023 07:21:51 +0700 Subject: [PATCH 057/101] fix: mkdir cmd --- src/user-shell.c | 105 ++++++++++++++++++++++++++++++----------------- 1 file changed, 67 insertions(+), 38 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index cab884b..02d9433 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -320,7 +320,7 @@ uint8_t cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory dir_table = request.buf; - memcpy(request.name, temp_info.paths[temp_info.current_path_count-1], DIRECTORY_NAME_LENGTH); + memcpy(request.name, temp_info.paths[temp_info.current_path_count - 1], DIRECTORY_NAME_LENGTH); request.parent_cluster_number = dir_table->table->cluster_low; } @@ -376,7 +376,7 @@ uint8_t cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory char errorMsg[] = "Error: directory not found\n"; syscall(5, (uint32_t)errorMsg, 28, 0xF); - + return 0; } } @@ -394,9 +394,11 @@ void ls_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf struct CurrentDirectoryInfo temp_info = {}; copy_directory_info(&temp_info, &info); - if ((uint32_t) indexes != 0) { + if ((uint32_t)indexes != 0) + { int status = cd_command(buf, indexes, &temp_info); - if (!status) return; + if (!status) + return; } struct ClusterBuffer cl[5]; @@ -418,7 +420,6 @@ void ls_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf memcpy(request.name, temp_info.paths[temp_info.current_path_count - 1], DIRECTORY_NAME_LENGTH); } - int32_t retcode; syscall(1, (uint32_t)&request, (uint32_t)&retcode, 0); @@ -437,16 +438,19 @@ void ls_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf { uint32_t color; - if (dirTable[i].table[j].attribute == ATTR_SUBDIRECTORY) color = 0xa; - else color = 0xf; + if (dirTable[i].table[j].attribute == ATTR_SUBDIRECTORY) + color = 0xa; + else + color = 0xf; syscall(5, (uint32_t)dirTable[i].table[j].name, DIRECTORY_NAME_LENGTH, color); - if (j < dirTable[i].table->n_of_entries - 1 || i < dir_table_count - 1) print_space(); + if (j < dirTable[i].table->n_of_entries - 1 || i < dir_table_count - 1) + print_space(); j++; } i++; } - + print_newline(); } @@ -456,7 +460,6 @@ void ls_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf syscall(5, (uint32_t)msg, 26, 0xF); syscall(5, (uint32_t)request.name, DIRECTORY_NAME_LENGTH, 0xF); print_newline(); - } } @@ -476,7 +479,6 @@ void parse_path_for_cd(char *buf, struct IndexInfo *indexes, struct IndexInfo *n get_buffer_indexes(buf, new_path_indexes, '/', indexes[1].index, indexes[1].length); } - /** * Invoking cd command from another command * @@ -487,18 +489,19 @@ void parse_path_for_cd(char *buf, struct IndexInfo *indexes, struct IndexInfo *n * @param target_directory new directory info after invoking cd command * @param target_name parsed target name from buffer * - * @return - + * @return 0: fail; + * 1: success; */ -void invoke_cd(char *buf, - int target_buf_length, - struct IndexInfo *new_path_indexes, - struct CurrentDirectoryInfo *target_directory, - char *target_name) +uint8_t invoke_cd(char *buf, + int target_buf_length, + struct IndexInfo *new_path_indexes, + struct CurrentDirectoryInfo *target_directory, + char *target_name) { int i = 0; while (!is_default_index(new_path_indexes[i + 1])) { - target_buf_length += new_path_indexes[i].length; + target_buf_length += new_path_indexes[i].length + 1; i++; } @@ -516,10 +519,9 @@ void invoke_cd(char *buf, target_buff[i] = buf[i]; } // call cd command to move the directory - cd_command(target_buff, new_path_indexes, target_directory); - - // TODO: handle failed cd + return cd_command(target_buff, new_path_indexes, target_directory); } + return 1; } /** @@ -531,7 +533,7 @@ void invoke_cd(char *buf, * * @return - */ -void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInfo *info) +void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInfo info) { // convert "mkdir" to "cd " buf[0] = 'c'; // m @@ -556,10 +558,13 @@ void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory // temporary CurrentDirectoryInfo for creating the new directory struct CurrentDirectoryInfo target_directory = {}; - copy_directory_info(&target_directory, info); + copy_directory_info(&target_directory, &info); char target_name[target_name_length]; - invoke_cd(buf, 6, new_path_indexes, &target_directory, target_name); + uint8_t cd_res = invoke_cd(buf, 6, new_path_indexes, &target_directory, target_name); + + if (cd_res == 0) + return; // create new directory in the target_directory struct ClusterBuffer cl[5]; @@ -567,19 +572,13 @@ void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory .buf = &cl, .ext = EMPTY_EXTENSION, .parent_cluster_number = target_directory.current_cluster_number, - .buffer_size = CLUSTER_SIZE * 5, + .buffer_size = 0, }; memcpy(write_request.name, target_name, target_name_length); int32_t retcode; - syscall(2, (uint32_t)&write_request, (uint32_t)&retcode, 0); - - if (retcode != 0) - { - // failed to create new directory - } } /** @@ -591,7 +590,7 @@ void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory * * @return - */ -void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInfo *info) +void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInfo info) { // convert "cat" to "cd " buf[0] = 'c'; // c @@ -603,11 +602,16 @@ void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryIn // temporary CurrentDirectoryInfo for creating the new directory struct CurrentDirectoryInfo target_directory = {}; - copy_directory_info(&target_directory, info); + copy_directory_info(&target_directory, &info); int target_name_length = new_path_indexes[get_words_count(new_path_indexes) - 1].length; char target_name[target_name_length]; - invoke_cd(buf, 6, new_path_indexes, &target_directory, target_name); + uint8_t cd_res = invoke_cd(buf, 4, new_path_indexes, &target_directory, target_name); + syscall(5, (uint32_t)target_name, target_name_length, 0xF); + print_newline(); + + if (cd_res == 0) + return; // read the file from FATtable struct ClusterBuffer cl[5]; @@ -627,6 +631,7 @@ void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryIn if (split_result != 0 && split_result != 1) { syscall(5, (uint32_t) "Invalid command!", 16, 0xF); + print_newline(); return; } memcpy(read_request.ext, target_file_name_extension.word, target_file_name_extension.length); @@ -642,7 +647,7 @@ void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryIn } else { - syscall(5, (uint32_t) "File not found", 14, 0xF); + syscall(5, (uint32_t) "File not found!", 14, 0xF); print_newline(); } } @@ -919,7 +924,7 @@ int main(void) if (argsCount == 1) { cd_command(buf, (uint32_t)0, ¤t_directory_info); - } + } else if (argsCount == 2) { cd_command(buf, word_indexes + 1, ¤t_directory_info); @@ -932,8 +937,8 @@ int main(void) else if (commandNumber == 1) { if (argsCount == 1) - ls_command(buf, (uint32_t) 0, current_directory_info); - + ls_command(buf, (uint32_t)0, current_directory_info); + else if (argsCount == 2) ls_command(buf, word_indexes + 1, current_directory_info); else @@ -942,10 +947,34 @@ int main(void) else if (commandNumber == 2) { + if (argsCount == 1) + { + syscall(5, (uint32_t) "Please give the folder path and name!\n", 39, 0xF); + } + else if (argsCount == 2) + { + mkdir_command(buf, word_indexes, current_directory_info); + } + else + { + syscall(5, (uint32_t)too_many_args_msg, 20, 0xF); + } } else if (commandNumber == 3) { + if (argsCount == 1) + { + syscall(5, (uint32_t) "Please give the file path and name!\n", 39, 0xF); + } + else if (argsCount == 2) + { + cat_command(buf, word_indexes, current_directory_info); + } + else + { + syscall(5, (uint32_t)too_many_args_msg, 20, 0xF); + } } else if (commandNumber == 4) From 19b2cb053170bce216bcaf18cdf228e9f1dd7f64 Mon Sep 17 00:00:00 2001 From: Fatih20 Date: Sat, 29 Apr 2023 09:43:44 +0700 Subject: [PATCH 058/101] Initial work on recursive deletion. --- src/fat32.c | 60 +++++++++++++++++++++++++++++++++++++++++- src/lib-header/fat32.h | 7 +++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/src/fat32.c b/src/fat32.c index df61a35..8af353b 100644 --- a/src/fat32.c +++ b/src/fat32.c @@ -577,9 +577,14 @@ int8_t delete(struct FAT32DriverRequest request, bool is_recursive, bool check_r return 5; } + // Delete the directory's content + delete_subdirectory_content(entry->cluster_low); + // Reset the read clusters to the initial state of the function read_clusters(&driver_state.dir_table_buf, request.parent_cluster_number, 1); - // Start recursive deletion + + // Delete the directory itself + delete_subdirectory_by_entry(entry, request); return 0; } @@ -1066,6 +1071,59 @@ bool is_below_max_recursion_depth(uint16_t target_cluster_number, uint8_t recurs return TRUE; } +void delete_subdirectory_content(uint16_t target_cluster_number) +{ + + read_clusters(&driver_state.dir_table_buf, target_cluster_number, 1); + + struct FAT32DriverRequest req = + { + .parent_cluster_number = target_cluster_number}; + + // Iterate through the directory entries and delete all + bool end_of_directory = FALSE; + struct FAT32DirectoryEntry *entry; + + uint16_t now_cluster_number = target_cluster_number; + uint16_t prev_cluster_number; + + while (!end_of_directory) + { + for (uint8_t i = 1; i < CLUSTER_SIZE / sizeof(struct FAT32DirectoryEntry); + i++) + { + entry = &(driver_state.dir_table_buf.table[i]); + if (is_subdirectory(entry)) + { + delete (req, TRUE, FALSE); + } + else + { + delete_file_by_entry(entry, req); + } + } + + // If the cluster_number is EOF, then we've finished examining the last + // cluster of the directory + end_of_directory = (driver_state.fat_table.cluster_map[now_cluster_number] & + 0x0000FFFF) == 0xFFFF; + + // Take notes of the latest_cluster_number for the proper copying of + // directory table + prev_cluster_number = now_cluster_number; + + // Move onto the next cluster if it's not the end yet + if (!end_of_directory) + { + now_cluster_number = + driver_state.fat_table.cluster_map[now_cluster_number]; + req.parent_cluster_number = now_cluster_number; + read_clusters(&driver_state.dir_table_buf, (uint32_t)now_cluster_number, + 1); + } + } +} + // uint32_t read_cluster_number(char** directories, int count, uint16_t latest_parent_cluster_number) { // // return ROOT_CLUSTER_NUMBER if not found diff --git a/src/lib-header/fat32.h b/src/lib-header/fat32.h index 4706689..7635b39 100644 --- a/src/lib-header/fat32.h +++ b/src/lib-header/fat32.h @@ -497,4 +497,11 @@ void set_access_datetime(struct FAT32DirectoryEntry *entry); */ bool is_below_max_recursion_depth(uint16_t target_cluster_number, uint8_t recursion_count); +/** + * @brief Delete the content of a subdirectory + * + * @param target_cluster_number the cluster number where the subdirectory is collected + */ +void delete_subdirectory_content(uint16_t target_cluster_number); + #endif From b4ce6099923e2c26bcb8d2d75b85f60e583facd3 Mon Sep 17 00:00:00 2001 From: Fatih20 Date: Sat, 29 Apr 2023 09:50:29 +0700 Subject: [PATCH 059/101] Fix compiler warning. --- src/fat32.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/fat32.c b/src/fat32.c index 8af353b..b311a42 100644 --- a/src/fat32.c +++ b/src/fat32.c @@ -1032,7 +1032,6 @@ bool is_below_max_recursion_depth(uint16_t target_cluster_number, uint8_t recurs struct FAT32DirectoryEntry *entry; uint16_t now_cluster_number = target_cluster_number; - uint16_t prev_cluster_number; while (!end_of_directory) { @@ -1055,10 +1054,6 @@ bool is_below_max_recursion_depth(uint16_t target_cluster_number, uint8_t recurs end_of_directory = (driver_state.fat_table.cluster_map[now_cluster_number] & 0x0000FFFF) == 0xFFFF; - // Take notes of the latest_cluster_number for the proper copying of - // directory table - prev_cluster_number = now_cluster_number; - // Move onto the next cluster if it's not the end yet if (!end_of_directory) { @@ -1085,7 +1080,6 @@ void delete_subdirectory_content(uint16_t target_cluster_number) struct FAT32DirectoryEntry *entry; uint16_t now_cluster_number = target_cluster_number; - uint16_t prev_cluster_number; while (!end_of_directory) { @@ -1108,10 +1102,6 @@ void delete_subdirectory_content(uint16_t target_cluster_number) end_of_directory = (driver_state.fat_table.cluster_map[now_cluster_number] & 0x0000FFFF) == 0xFFFF; - // Take notes of the latest_cluster_number for the proper copying of - // directory table - prev_cluster_number = now_cluster_number; - // Move onto the next cluster if it's not the end yet if (!end_of_directory) { From 064da9397961afb37ff04ddd955f16a1854c00cc Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Sat, 29 Apr 2023 12:53:31 +0700 Subject: [PATCH 060/101] feat: add print extension in ls --- src/kernel.c | 6 +++--- src/user-shell.c | 9 +++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/kernel.c b/src/kernel.c index e1e980c..768a83a 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -42,7 +42,7 @@ void kernel_setup(void) write(req); // move parent to f1 - req.parent_cluster_number = 0x9; + req.parent_cluster_number = 0xa; memcpy(req.name, "f4", 2); write(req); @@ -51,12 +51,12 @@ void kernel_setup(void) write(req); // move parent to f1 - req.parent_cluster_number = 0xc; + req.parent_cluster_number = 0xd; memcpy(req.name, "f6", 2); write(req); - req.parent_cluster_number = 0xe; + req.parent_cluster_number = 0xf; memcpy(req.name, "f7", 2); write(req); diff --git a/src/user-shell.c b/src/user-shell.c index f05b3df..8373b7d 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -449,6 +449,15 @@ void ls_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf else color = 0xf; syscall(5, (uint32_t)dirTable[i].table[j].name, DIRECTORY_NAME_LENGTH, color); + + if (dirTable[i].table[j].attribute != ATTR_SUBDIRECTORY && memcmp(dirTable[i].table[j].ext, "\0\0\0", 3) != 0) + { + char point_str[] = "."; + syscall(5, (uint32_t)point_str, 1, color); + syscall(5, (uint32_t)dirTable[i].table[j].ext, 3, color); + + } + if (j < dirTable[i].table->n_of_entries - 1 || i < dir_table_count - 1) print_space(); j++; From 718cc08e9b6fc97bf0a84964cd76219c214a0dcc Mon Sep 17 00:00:00 2001 From: sozyGithub Date: Sat, 29 Apr 2023 12:59:12 +0700 Subject: [PATCH 061/101] rfc: invoke_cd --- src/user-shell.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index f05b3df..5c2fb22 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -508,9 +508,6 @@ uint8_t invoke_cd(char *buf, int new_buf_length = new_path_indexes[last_word_index - 1].index + new_path_indexes[last_word_index - 1].length; target_name->length = new_path_indexes[last_word_index].length; - char target_name_word[target_name->length]; - memcpy(target_name->word, target_name_word, target_name->length); - for (int j = new_path_indexes[last_word_index].index; j < new_path_indexes[last_word_index].index + new_path_indexes[last_word_index].length; j++) { target_name->word[j - new_path_indexes[last_word_index].index] = buf[j]; From 2b0712e3071feee354367153901cd9716c77a4a0 Mon Sep 17 00:00:00 2001 From: Genvictus Date: Sat, 29 Apr 2023 13:22:27 +0700 Subject: [PATCH 062/101] update: follows new implementation of invoke_cd --- src/user-shell.c | 63 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index f05b3df..ba03bef 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -732,7 +732,17 @@ void print_path(uint32_t cluster_number) } } -void cp_command(struct CurrentDirectoryInfo *source_dir, +/** + * cp command in shell, copy the file in specified source directory to the specified destination directory with new name + * @param source_dir directory of file to be copied + * @param source_name name of file to be copied in the specified directory + * @param dest_dir write destination directory of file to be copied + * @param dest_name name of file to be written in the destination directory + * @return 0: copy succeeded + * 1: unable to read file + * 2: unable to write file +*/ +uint8_t cp_command(struct CurrentDirectoryInfo *source_dir, struct ParseString *source_name, struct CurrentDirectoryInfo *dest_dir, struct ParseString *dest_name) @@ -751,7 +761,7 @@ void cp_command(struct CurrentDirectoryInfo *source_dir, if (splitcode == 2 || splitcode == 3) { char msg[] = "Source file not found!\n"; - syscall(5, (uint32_t)msg, 19, 0xF); + syscall(5, (uint32_t)msg, 24, 0xF); return; } @@ -780,7 +790,7 @@ void cp_command(struct CurrentDirectoryInfo *source_dir, if (splitcode == 2 || splitcode == 3) { char msg[] = "Source file not found!\n"; - syscall(5, (uint32_t)msg, 19, 0xF); + syscall(5, (uint32_t)msg, 24, 0xF); return; } @@ -807,6 +817,13 @@ void cp_command(struct CurrentDirectoryInfo *source_dir, } } +/** + * rm command in shell, removes the specified file in the specified directory + * @param file_dir directory of file to be removed + * @param file_name name of file in the specified directory to be removed + * + * @return - +*/ void rm_command(struct CurrentDirectoryInfo *file_dir, struct ParseString *file_name) { struct ParseString name; @@ -818,7 +835,7 @@ void rm_command(struct CurrentDirectoryInfo *file_dir, struct ParseString *file_ if (splitcode == 2 || splitcode == 3) { char msg[] = "Source file not found!\n"; - syscall(5, (uint32_t)msg, 19, 0xF); + syscall(5, (uint32_t)msg, 24, 0xF); return; } @@ -972,21 +989,24 @@ int main(void) else if (commandNumber == 4) { // cp_command - struct CurrentDirectoryInfo source_dir = current_directory_info; - struct CurrentDirectoryInfo dest_dir = current_directory_info; + struct CurrentDirectoryInfo source_dir = { + .current_cluster_number = current_directory_info.current_cluster_number + }; + struct CurrentDirectoryInfo dest_dir = { + .current_cluster_number = current_directory_info.current_cluster_number + }; struct ParseString source_name; struct ParseString dest_name; // get source directory info & source file name struct IndexInfo new_path_indexes[INDEXES_MAX_COUNT]; - parse_path_for_cd(buf, word_indexes, new_path_indexes); - invoke_cd(buf, new_path_indexes, &source_dir, &source_name); + reset_indexes(new_path_indexes, INDEXES_MAX_COUNT); + invoke_cd(buf, word_indexes+1, &source_dir, &source_name); // get destination directory info & source file name reset_indexes(new_path_indexes, INDEXES_MAX_COUNT); - parse_path_for_cd(buf, word_indexes + 1, new_path_indexes); - invoke_cd(buf, new_path_indexes, &dest_dir, &dest_name); + invoke_cd(buf, word_indexes+2, &dest_dir, &dest_name); // invoke cp command cp_command(&source_dir, &source_name, &dest_dir, &dest_name); @@ -995,14 +1015,16 @@ int main(void) else if (commandNumber == 5) { // rm_command - struct CurrentDirectoryInfo target_dir = current_directory_info; + struct CurrentDirectoryInfo target_dir = { + .current_cluster_number = current_directory_info.current_cluster_number + }; struct ParseString target_name; // get source directory info & source file name struct IndexInfo new_path_indexes[INDEXES_MAX_COUNT]; - parse_path_for_cd(buf, word_indexes, new_path_indexes); - invoke_cd(buf, new_path_indexes, &target_dir, &target_name); + reset_indexes(new_path_indexes, INDEXES_MAX_COUNT); + invoke_cd(buf, word_indexes+1, &target_dir, &target_name); // invoke cp command rm_command(&target_dir, &target_name); @@ -1011,21 +1033,24 @@ int main(void) else if (commandNumber == 6) { // mv_command - struct CurrentDirectoryInfo source_dir = current_directory_info; - struct CurrentDirectoryInfo dest_dir = current_directory_info; + struct CurrentDirectoryInfo source_dir = { + .current_cluster_number = current_directory_info.current_cluster_number + }; + struct CurrentDirectoryInfo dest_dir = { + .current_cluster_number = current_directory_info.current_cluster_number + }; struct ParseString source_name; struct ParseString dest_name; // get source directory info & source file name struct IndexInfo new_path_indexes[INDEXES_MAX_COUNT]; - parse_path_for_cd(buf, word_indexes, new_path_indexes); - invoke_cd(buf, new_path_indexes, &source_dir, &source_name); + reset_indexes(new_path_indexes, INDEXES_MAX_COUNT); + invoke_cd(buf, word_indexes+1, &source_dir, &source_name); // get destination directory info & source file name reset_indexes(new_path_indexes, INDEXES_MAX_COUNT); - parse_path_for_cd(buf, word_indexes + 1, new_path_indexes); - invoke_cd(buf, new_path_indexes, &dest_dir, &dest_name); + invoke_cd(buf, word_indexes+2, &dest_dir, &dest_name); // invoke cp command mv_command(&source_dir, &source_name, &dest_dir, &dest_name); From 85ce1db4c558129c17c3eefc19214d6ebfeffd29 Mon Sep 17 00:00:00 2001 From: sozyGithub Date: Sat, 29 Apr 2023 13:07:14 +0700 Subject: [PATCH 063/101] temp-fix error while compiling --- src/user-shell.c | 43 +++++++++++++++++++------------------------ 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index 34796ba..62dd3b8 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -455,7 +455,6 @@ void ls_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf char point_str[] = "."; syscall(5, (uint32_t)point_str, 1, color); syscall(5, (uint32_t)dirTable[i].table[j].ext, 3, color); - } if (j < dirTable[i].table->n_of_entries - 1 || i < dir_table_count - 1) @@ -747,11 +746,11 @@ void print_path(uint32_t cluster_number) * @return 0: copy succeeded * 1: unable to read file * 2: unable to write file -*/ + */ uint8_t cp_command(struct CurrentDirectoryInfo *source_dir, - struct ParseString *source_name, - struct CurrentDirectoryInfo *dest_dir, - struct ParseString *dest_name) + struct ParseString *source_name, + struct CurrentDirectoryInfo *dest_dir, + struct ParseString *dest_name) { // prepare buffer in memory for copying struct ClusterBuffer cl[MAX_FILE_BUFFER_CLUSTER_SIZE]; @@ -768,7 +767,7 @@ uint8_t cp_command(struct CurrentDirectoryInfo *source_dir, { char msg[] = "Source file not found!\n"; syscall(5, (uint32_t)msg, 24, 0xF); - return; + // return; } // prepare read file request @@ -797,7 +796,7 @@ uint8_t cp_command(struct CurrentDirectoryInfo *source_dir, { char msg[] = "Source file not found!\n"; syscall(5, (uint32_t)msg, 24, 0xF); - return; + // return; } // prepare write file request @@ -821,15 +820,16 @@ uint8_t cp_command(struct CurrentDirectoryInfo *source_dir, { // try read folder } + return 0; } /** * rm command in shell, removes the specified file in the specified directory * @param file_dir directory of file to be removed * @param file_name name of file in the specified directory to be removed - * + * * @return - -*/ + */ void rm_command(struct CurrentDirectoryInfo *file_dir, struct ParseString *file_name) { struct ParseString name; @@ -996,11 +996,9 @@ int main(void) { // cp_command struct CurrentDirectoryInfo source_dir = { - .current_cluster_number = current_directory_info.current_cluster_number - }; + .current_cluster_number = current_directory_info.current_cluster_number}; struct CurrentDirectoryInfo dest_dir = { - .current_cluster_number = current_directory_info.current_cluster_number - }; + .current_cluster_number = current_directory_info.current_cluster_number}; struct ParseString source_name; struct ParseString dest_name; @@ -1008,11 +1006,11 @@ int main(void) // get source directory info & source file name struct IndexInfo new_path_indexes[INDEXES_MAX_COUNT]; reset_indexes(new_path_indexes, INDEXES_MAX_COUNT); - invoke_cd(buf, word_indexes+1, &source_dir, &source_name); + invoke_cd(buf, word_indexes + 1, &source_dir, &source_name); // get destination directory info & source file name reset_indexes(new_path_indexes, INDEXES_MAX_COUNT); - invoke_cd(buf, word_indexes+2, &dest_dir, &dest_name); + invoke_cd(buf, word_indexes + 2, &dest_dir, &dest_name); // invoke cp command cp_command(&source_dir, &source_name, &dest_dir, &dest_name); @@ -1022,15 +1020,14 @@ int main(void) { // rm_command struct CurrentDirectoryInfo target_dir = { - .current_cluster_number = current_directory_info.current_cluster_number - }; + .current_cluster_number = current_directory_info.current_cluster_number}; struct ParseString target_name; // get source directory info & source file name struct IndexInfo new_path_indexes[INDEXES_MAX_COUNT]; reset_indexes(new_path_indexes, INDEXES_MAX_COUNT); - invoke_cd(buf, word_indexes+1, &target_dir, &target_name); + invoke_cd(buf, word_indexes + 1, &target_dir, &target_name); // invoke cp command rm_command(&target_dir, &target_name); @@ -1040,11 +1037,9 @@ int main(void) { // mv_command struct CurrentDirectoryInfo source_dir = { - .current_cluster_number = current_directory_info.current_cluster_number - }; + .current_cluster_number = current_directory_info.current_cluster_number}; struct CurrentDirectoryInfo dest_dir = { - .current_cluster_number = current_directory_info.current_cluster_number - }; + .current_cluster_number = current_directory_info.current_cluster_number}; struct ParseString source_name; struct ParseString dest_name; @@ -1052,11 +1047,11 @@ int main(void) // get source directory info & source file name struct IndexInfo new_path_indexes[INDEXES_MAX_COUNT]; reset_indexes(new_path_indexes, INDEXES_MAX_COUNT); - invoke_cd(buf, word_indexes+1, &source_dir, &source_name); + invoke_cd(buf, word_indexes + 1, &source_dir, &source_name); // get destination directory info & source file name reset_indexes(new_path_indexes, INDEXES_MAX_COUNT); - invoke_cd(buf, word_indexes+2, &dest_dir, &dest_name); + invoke_cd(buf, word_indexes + 2, &dest_dir, &dest_name); // invoke cp command mv_command(&source_dir, &source_name, &dest_dir, &dest_name); From f1ece60433dfa7ef51cbf631e05c1b90906fa4e3 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Sat, 29 Apr 2023 13:48:46 +0700 Subject: [PATCH 064/101] fix: color in scrolling --- src/keyboard.c | 2 +- src/user-shell.c | 39 ++++++++++++++++----------------------- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/src/keyboard.c b/src/keyboard.c index 66f2a29..fd9a3b5 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -167,7 +167,7 @@ void scroll_behavior(void){ for(uint8_t row = 1; row < 25; row++){ for(uint8_t col = 0; col < 80; col++){ uint8_t move = *(location + row*80 + col) & 0x00FF; - framebuffer_write(row-1, col, move, 0xF, 0); + framebuffer_write(row-1, col, move, (*(location + row*80 + col) & 0xFF00) >> 8, 0); } } diff --git a/src/user-shell.c b/src/user-shell.c index 8373b7d..0b61e34 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -517,13 +517,7 @@ uint8_t invoke_cd(char *buf, int new_buf_length = new_path_indexes[last_word_index - 1].index + new_path_indexes[last_word_index - 1].length; target_name->length = new_path_indexes[last_word_index].length; - char target_name_word[target_name->length]; - memcpy(target_name->word, target_name_word, target_name->length); - - for (int j = new_path_indexes[last_word_index].index; j < new_path_indexes[last_word_index].index + new_path_indexes[last_word_index].length; j++) - { - target_name->word[j - new_path_indexes[last_word_index].index] = buf[j]; - } + memcpy(target_name->word, buf + last_word_index, target_name->length); if (get_words_count(new_path_indexes) > 1) { @@ -760,7 +754,7 @@ void cp_command(struct CurrentDirectoryInfo *source_dir, if (splitcode == 2 || splitcode == 3) { char msg[] = "Source file not found!\n"; - syscall(5, (uint32_t)msg, 19, 0xF); + syscall(5, (uint32_t)msg, 24, 0xF); return; } @@ -1004,14 +998,14 @@ int main(void) else if (commandNumber == 5) { // rm_command - struct CurrentDirectoryInfo target_dir = current_directory_info; + struct CurrentDirectoryInfo target_dir; + copy_directory_info(&target_dir,¤t_directory_info); - struct ParseString target_name; + struct ParseString target_name = {}; + reset_buffer(target_name.word, SHELL_BUFFER_SIZE); // get source directory info & source file name - struct IndexInfo new_path_indexes[INDEXES_MAX_COUNT]; - parse_path_for_cd(buf, word_indexes, new_path_indexes); - invoke_cd(buf, new_path_indexes, &target_dir, &target_name); + invoke_cd(buf, word_indexes+1, &target_dir, &target_name); // invoke cp command rm_command(&target_dir, &target_name); @@ -1020,21 +1014,20 @@ int main(void) else if (commandNumber == 6) { // mv_command - struct CurrentDirectoryInfo source_dir = current_directory_info; - struct CurrentDirectoryInfo dest_dir = current_directory_info; + struct CurrentDirectoryInfo source_dir = {}; + struct CurrentDirectoryInfo dest_dir = {}; - struct ParseString source_name; - struct ParseString dest_name; + copy_directory_info(&source_dir, ¤t_directory_info); + copy_directory_info(&dest_dir, ¤t_directory_info); + + struct ParseString source_name = {}; + struct ParseString dest_name = {}; // get source directory info & source file name - struct IndexInfo new_path_indexes[INDEXES_MAX_COUNT]; - parse_path_for_cd(buf, word_indexes, new_path_indexes); - invoke_cd(buf, new_path_indexes, &source_dir, &source_name); + invoke_cd(buf, word_indexes+1, &source_dir, &source_name); // get destination directory info & source file name - reset_indexes(new_path_indexes, INDEXES_MAX_COUNT); - parse_path_for_cd(buf, word_indexes + 1, new_path_indexes); - invoke_cd(buf, new_path_indexes, &dest_dir, &dest_name); + invoke_cd(buf, word_indexes+2, &dest_dir, &dest_name); // invoke cp command mv_command(&source_dir, &source_name, &dest_dir, &dest_name); From 4b811e549bdd988fc14cefce4693eb9d93b8d560 Mon Sep 17 00:00:00 2001 From: Genvictus Date: Sat, 29 Apr 2023 14:13:11 +0700 Subject: [PATCH 065/101] fix: split_filename now applies reset_indexes before processing --- src/user-shell.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/user-shell.c b/src/user-shell.c index 62dd3b8..c5e36b5 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -204,6 +204,7 @@ int split_filename_extension(struct ParseString *filename, // parse filename to name and extension struct IndexInfo temp_index[INDEXES_MAX_COUNT]; + reset_indexes(temp_index, INDEXES_MAX_COUNT); get_buffer_indexes(filename->word, temp_index, '.', 0, filename->length); int words_count = get_words_count(temp_index); From 5b4ece5da2f734482ffe45aaef1ff85415f6a913 Mon Sep 17 00:00:00 2001 From: Genvictus Date: Sat, 29 Apr 2023 14:22:04 +0700 Subject: [PATCH 066/101] rfc: comments and unnecessary lines --- src/user-shell.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index cfd8474..a3e6657 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -1004,13 +1004,10 @@ int main(void) struct ParseString dest_name; // get source directory info & source file name - struct IndexInfo new_path_indexes[INDEXES_MAX_COUNT]; - reset_indexes(new_path_indexes, INDEXES_MAX_COUNT); - invoke_cd(buf, word_indexes + 1, &source_dir, &source_name); + invoke_cd(buf, word_indexes+1, &source_dir, &source_name); // get destination directory info & source file name - reset_indexes(new_path_indexes, INDEXES_MAX_COUNT); - invoke_cd(buf, word_indexes + 2, &dest_dir, &dest_name); + invoke_cd(buf, word_indexes+2, &dest_dir, &dest_name); // invoke cp command cp_command(&source_dir, &source_name, &dest_dir, &dest_name); @@ -1026,10 +1023,9 @@ int main(void) reset_buffer(target_name.word, SHELL_BUFFER_SIZE); // get source directory info & source file name - invoke_cd(buf, word_indexes+1, &target_dir, &target_name); - // invoke cp command + // invoke rm command rm_command(&target_dir, &target_name); } @@ -1052,7 +1048,7 @@ int main(void) // get destination directory info & source file name invoke_cd(buf, word_indexes+2, &dest_dir, &dest_name); - // invoke cp command + // invoke mv command mv_command(&source_dir, &source_name, &dest_dir, &dest_name); } From 59e2da49b2026289d291d0cb43eb53ea5d279eca Mon Sep 17 00:00:00 2001 From: Genvictus Date: Sat, 29 Apr 2023 14:57:40 +0700 Subject: [PATCH 067/101] bug fix --- src/user-shell.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index cfd8474..25551f9 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -517,7 +517,7 @@ uint8_t invoke_cd(char *buf, int new_buf_length = new_path_indexes[last_word_index - 1].index + new_path_indexes[last_word_index - 1].length; target_name->length = new_path_indexes[last_word_index].length; - memcpy(target_name->word, buf + last_word_index, target_name->length); + memcpy(target_name->word, buf + new_path_indexes[last_word_index].index, target_name->length); if (get_words_count(new_path_indexes) > 1) { @@ -772,7 +772,7 @@ uint8_t cp_command(struct CurrentDirectoryInfo *source_dir, // prepare read file request struct FAT32DriverRequest read_request = { - .buf = &cl, + .buf = cl, // .name = EMPTY_NAME, .ext = EMPTY_EXTENSION, .parent_cluster_number = source_dir->current_cluster_number, @@ -801,7 +801,7 @@ uint8_t cp_command(struct CurrentDirectoryInfo *source_dir, // prepare write file request struct FAT32DriverRequest write_request = { - .buf = &cl, + .buf = cl, // .name = EMPTY_NAME, .ext = EMPTY_EXTENSION, .parent_cluster_number = dest_dir->current_cluster_number, @@ -830,7 +830,7 @@ uint8_t cp_command(struct CurrentDirectoryInfo *source_dir, * * @return - */ -void rm_command(struct CurrentDirectoryInfo *file_dir, struct ParseString *file_name) +int8_t rm_command(struct CurrentDirectoryInfo *file_dir, struct ParseString *file_name) { struct ParseString name; struct ParseString ext; @@ -842,7 +842,7 @@ void rm_command(struct CurrentDirectoryInfo *file_dir, struct ParseString *file_ { char msg[] = "Source file not found!\n"; syscall(5, (uint32_t)msg, 24, 0xF); - return; + return 1; } // create delete request @@ -854,8 +854,10 @@ void rm_command(struct CurrentDirectoryInfo *file_dir, struct ParseString *file_ memcpy(delete_request.name, name.word, name.length); memcpy(delete_request.ext, ext.word, ext.length); - int32_t retcode; + int8_t retcode; syscall(3, (uint32_t)&delete_request, (uint32_t)&retcode, 0); + + return retcode; } void mv_command(struct CurrentDirectoryInfo *source_dir, From 977abc52e9bb456adb90346abea020a20f34fb4a Mon Sep 17 00:00:00 2001 From: Fatih20 Date: Sat, 29 Apr 2023 14:59:50 +0700 Subject: [PATCH 068/101] Reorder delete function for convenience. --- src/fat32.c | 214 +++++++++++++++++++++++------------------------ src/user-shell.c | 3 +- 2 files changed, 109 insertions(+), 108 deletions(-) diff --git a/src/fat32.c b/src/fat32.c index b311a42..680100a 100644 --- a/src/fat32.c +++ b/src/fat32.c @@ -580,7 +580,7 @@ int8_t delete(struct FAT32DriverRequest request, bool is_recursive, bool check_r // Delete the directory's content delete_subdirectory_content(entry->cluster_low); - // Reset the read clusters to the initial state of the function + // Reset the read clusters to the cluster where the entry of the directory to be deleted is located in the directory table read_clusters(&driver_state.dir_table_buf, request.parent_cluster_number, 1); // Delete the directory itself @@ -589,6 +589,112 @@ int8_t delete(struct FAT32DriverRequest request, bool is_recursive, bool check_r return 0; } +void delete_subdirectory_by_entry(struct FAT32DirectoryEntry *entry, + struct FAT32DriverRequest req) +{ + + uint16_t now_cluster_number = entry->cluster_low; + uint16_t next_cluster_number; + do + { + next_cluster_number = + (uint16_t)(driver_state.fat_table.cluster_map[now_cluster_number] & + 0xFFFF); + driver_state.fat_table.cluster_map[now_cluster_number] = (uint32_t)0; + reset_cluster(now_cluster_number); + now_cluster_number = next_cluster_number; + } while (now_cluster_number != 0xFFFF); + + memcpy(entry->name, "\0\0\0\0\0\0\0\0", 8); + entry->user_attribute = (uint8_t)0; + entry->attribute = (uint8_t)0; + driver_state.fat_table.cluster_map[entry->cluster_low] = (uint32_t)0; + entry->cluster_high = (uint16_t)0; + entry->cluster_low = (uint16_t)0; + + // Decrement the number of entry in its targeted parent's directory table + decrement_subdir_n_of_entry(&(driver_state.dir_table_buf)); + + write_clusters(&driver_state.fat_table, 1, 1); + write_clusters(&driver_state.dir_table_buf, req.parent_cluster_number, 1); +} + +void delete_file_by_entry(struct FAT32DirectoryEntry *entry, + struct FAT32DriverRequest req) +{ + uint16_t now_cluster_number = entry->cluster_low; + uint16_t next_cluster_number; + do + { + next_cluster_number = + (uint16_t)(driver_state.fat_table.cluster_map[now_cluster_number] & + 0xFFFF); + driver_state.fat_table.cluster_map[now_cluster_number] = (uint32_t)0; + reset_cluster(now_cluster_number); + now_cluster_number = next_cluster_number; + } while (now_cluster_number != 0xFFFF); + memcpy(entry->name, "\0\0\0\0\0\0\0\0", 8); + memcpy(entry->ext, "\0\0\0", 3); + entry->cluster_high = 0; + entry->cluster_low = 0; + entry->user_attribute = 0; + entry->attribute = 0; + + // Decrement the number of entry in its targeted parent's directory table + decrement_subdir_n_of_entry(&(driver_state.dir_table_buf)); + + write_clusters(&driver_state.fat_table, 1, 1); + write_clusters(&driver_state.dir_table_buf, req.parent_cluster_number, 1); +} + +void delete_subdirectory_content(uint16_t target_cluster_number) +{ + + read_clusters(&driver_state.dir_table_buf, target_cluster_number, 1); + + struct FAT32DriverRequest req = + { + .parent_cluster_number = target_cluster_number}; + + // Iterate through the directory entries and delete all + bool end_of_directory = FALSE; + struct FAT32DirectoryEntry *entry; + + uint16_t now_cluster_number = target_cluster_number; + + while (!end_of_directory) + { + for (uint8_t i = 1; i < CLUSTER_SIZE / sizeof(struct FAT32DirectoryEntry); + i++) + { + entry = &(driver_state.dir_table_buf.table[i]); + if (is_subdirectory(entry)) + { + delete (req, TRUE, FALSE); + } + else + { + delete_file_by_entry(entry, req); + } + } + + // If the cluster_number is EOF, then we've finished examining the last + // cluster of the directory + end_of_directory = (driver_state.fat_table.cluster_map[now_cluster_number] & + 0x0000FFFF) == 0xFFFF; + + // Move onto the next cluster if it's not the end yet + if (!end_of_directory) + { + now_cluster_number = + driver_state.fat_table.cluster_map[now_cluster_number]; + req.parent_cluster_number = now_cluster_number; + read_clusters(&driver_state.dir_table_buf, (uint32_t)now_cluster_number, + 1); + } + } +} + bool is_entry_empty(struct FAT32DirectoryEntry *entry) { return entry->user_attribute != UATTR_NOT_EMPTY; @@ -723,64 +829,6 @@ void reset_cluster(uint32_t cluster_number) write_clusters(empty_cluster_value, cluster_number, 1); } -void delete_subdirectory_by_entry(struct FAT32DirectoryEntry *entry, - struct FAT32DriverRequest req) -{ - - uint16_t now_cluster_number = entry->cluster_low; - uint16_t next_cluster_number; - do - { - next_cluster_number = - (uint16_t)(driver_state.fat_table.cluster_map[now_cluster_number] & - 0xFFFF); - driver_state.fat_table.cluster_map[now_cluster_number] = (uint32_t)0; - reset_cluster(now_cluster_number); - now_cluster_number = next_cluster_number; - } while (now_cluster_number != 0xFFFF); - - memcpy(entry->name, "\0\0\0\0\0\0\0\0", 8); - entry->user_attribute = (uint8_t)0; - entry->attribute = (uint8_t)0; - driver_state.fat_table.cluster_map[entry->cluster_low] = (uint32_t)0; - entry->cluster_high = (uint16_t)0; - entry->cluster_low = (uint16_t)0; - - // Decrement the number of entry in its targeted parent's directory table - decrement_subdir_n_of_entry(&(driver_state.dir_table_buf)); - - write_clusters(&driver_state.fat_table, 1, 1); - write_clusters(&driver_state.dir_table_buf, req.parent_cluster_number, 1); -} - -void delete_file_by_entry(struct FAT32DirectoryEntry *entry, - struct FAT32DriverRequest req) -{ - uint16_t now_cluster_number = entry->cluster_low; - uint16_t next_cluster_number; - do - { - next_cluster_number = - (uint16_t)(driver_state.fat_table.cluster_map[now_cluster_number] & - 0xFFFF); - driver_state.fat_table.cluster_map[now_cluster_number] = (uint32_t)0; - reset_cluster(now_cluster_number); - now_cluster_number = next_cluster_number; - } while (now_cluster_number != 0xFFFF); - memcpy(entry->name, "\0\0\0\0\0\0\0\0", 8); - memcpy(entry->ext, "\0\0\0", 3); - entry->cluster_high = 0; - entry->cluster_low = 0; - entry->user_attribute = 0; - entry->attribute = 0; - - // Decrement the number of entry in its targeted parent's directory table - decrement_subdir_n_of_entry(&(driver_state.dir_table_buf)); - - write_clusters(&driver_state.fat_table, 1, 1); - write_clusters(&driver_state.dir_table_buf, req.parent_cluster_number, 1); -} - void read_directory_by_entry(struct FAT32DirectoryEntry *entry, struct FAT32DriverRequest req) { @@ -1066,54 +1114,6 @@ bool is_below_max_recursion_depth(uint16_t target_cluster_number, uint8_t recurs return TRUE; } -void delete_subdirectory_content(uint16_t target_cluster_number) -{ - - read_clusters(&driver_state.dir_table_buf, target_cluster_number, 1); - - struct FAT32DriverRequest req = - { - .parent_cluster_number = target_cluster_number}; - - // Iterate through the directory entries and delete all - bool end_of_directory = FALSE; - struct FAT32DirectoryEntry *entry; - - uint16_t now_cluster_number = target_cluster_number; - - while (!end_of_directory) - { - for (uint8_t i = 1; i < CLUSTER_SIZE / sizeof(struct FAT32DirectoryEntry); - i++) - { - entry = &(driver_state.dir_table_buf.table[i]); - if (is_subdirectory(entry)) - { - delete (req, TRUE, FALSE); - } - else - { - delete_file_by_entry(entry, req); - } - } - - // If the cluster_number is EOF, then we've finished examining the last - // cluster of the directory - end_of_directory = (driver_state.fat_table.cluster_map[now_cluster_number] & - 0x0000FFFF) == 0xFFFF; - - // Move onto the next cluster if it's not the end yet - if (!end_of_directory) - { - now_cluster_number = - driver_state.fat_table.cluster_map[now_cluster_number]; - req.parent_cluster_number = now_cluster_number; - read_clusters(&driver_state.dir_table_buf, (uint32_t)now_cluster_number, - 1); - } - } -} - // uint32_t read_cluster_number(char** directories, int count, uint16_t latest_parent_cluster_number) { // // return ROOT_CLUSTER_NUMBER if not found diff --git a/src/user-shell.c b/src/user-shell.c index 0d3a995..b3d54f2 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -828,6 +828,7 @@ void rm_command(struct CurrentDirectoryInfo *file_dir, struct ParseString *file_ .ext = EMPTY_EXTENSION, .parent_cluster_number = file_dir->current_cluster_number, }; + memcpy(delete_request.name, name.word, name.length); memcpy(delete_request.ext, ext.word, ext.length); @@ -1041,7 +1042,7 @@ int main(void) // get source directory info & source file name struct IndexInfo new_path_indexes[INDEXES_MAX_COUNT]; parse_path_for_cd(buf, word_indexes, new_path_indexes); - invoke_cd(buf, word_indexes[1].index, new_path_indexes, &target_dir, &target_name); + invoke_cd(buf, new_path_indexes, &target_dir, &target_name); // invoke rm recursive command rm_command(&target_dir, &target_name, TRUE); From 7fd0cf9feb59656c692470359a34b3d008369891 Mon Sep 17 00:00:00 2001 From: sozyGithub Date: Sat, 29 Apr 2023 16:15:26 +0700 Subject: [PATCH 069/101] add: handle args --- src/user-shell.c | 51 +++++++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index 7d052ff..109dce9 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -771,7 +771,6 @@ uint8_t cp_command(struct CurrentDirectoryInfo *source_dir, syscall(5, (uint32_t)msg, 24, 0xF); // return; - } // prepare read file request @@ -1010,10 +1009,10 @@ int main(void) struct ParseString dest_name; // get source directory info & source file name - invoke_cd(buf, word_indexes+1, &source_dir, &source_name); + invoke_cd(buf, word_indexes + 1, &source_dir, &source_name); // get destination directory info & source file name - invoke_cd(buf, word_indexes+2, &dest_dir, &dest_name); + invoke_cd(buf, word_indexes + 2, &dest_dir, &dest_name); // invoke cp command cp_command(&source_dir, &source_name, &dest_dir, &dest_name); @@ -1023,13 +1022,13 @@ int main(void) { // rm_command struct CurrentDirectoryInfo target_dir; - copy_directory_info(&target_dir,¤t_directory_info); + copy_directory_info(&target_dir, ¤t_directory_info); struct ParseString target_name = {}; reset_buffer(target_name.word, SHELL_BUFFER_SIZE); // get source directory info & source file name - invoke_cd(buf, word_indexes+1, &target_dir, &target_name); + invoke_cd(buf, word_indexes + 1, &target_dir, &target_name); // invoke rm command rm_command(&target_dir, &target_name); @@ -1038,24 +1037,40 @@ int main(void) else if (commandNumber == 6) { // mv_command + if (argsCount == 1) + { + syscall(5, (uint32_t) "Please give the source path!", 28, 0xF); + print_newline(); + } + else if (argsCount == 2) + { + syscall(5, (uint32_t) "Please give the destination path!", 33, 0xF); + print_newline(); + } + else if (argsCount == 3) + { + struct CurrentDirectoryInfo source_dir = {}; + struct CurrentDirectoryInfo dest_dir = {}; - struct CurrentDirectoryInfo source_dir = {}; - struct CurrentDirectoryInfo dest_dir = {}; - - copy_directory_info(&source_dir, ¤t_directory_info); - copy_directory_info(&dest_dir, ¤t_directory_info); + copy_directory_info(&source_dir, ¤t_directory_info); + copy_directory_info(&dest_dir, ¤t_directory_info); - struct ParseString source_name = {}; - struct ParseString dest_name = {}; + struct ParseString source_name = {}; + struct ParseString dest_name = {}; - // get source directory info & source file name - invoke_cd(buf, word_indexes+1, &source_dir, &source_name); + // get source directory info & source file name + invoke_cd(buf, word_indexes + 1, &source_dir, &source_name); - // get destination directory info & source file name - invoke_cd(buf, word_indexes+2, &dest_dir, &dest_name); + // get destination directory info & source file name + invoke_cd(buf, word_indexes + 2, &dest_dir, &dest_name); - // invoke mv command - mv_command(&source_dir, &source_name, &dest_dir, &dest_name); + // invoke mv command + mv_command(&source_dir, &source_name, &dest_dir, &dest_name); + } + else + { + syscall(5, (uint32_t)too_many_args_msg, 20, 0xF); + } } else if (commandNumber == 7) From 228fc7cb3e99bb2db5bbf8b1d3f851dd92f4c5eb Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Sat, 29 Apr 2023 16:21:39 +0700 Subject: [PATCH 070/101] fix: command parser --- src/user-shell.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/user-shell.c b/src/user-shell.c index 5d60549..7d052ff 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -144,7 +144,11 @@ int get_command_number(char *buf, int starting_index, int command_length) for (int i = 0; i < COMMAND_COUNT; i++) { - if (memcmp(buf + starting_index, command_list[i], command_length) == 0) + char command[COMMAND_MAX_SIZE]; + + reset_buffer(command, COMMAND_MAX_SIZE); + memcpy(command, buf + starting_index, command_length); + if (memcmp(command, command_list[i], COMMAND_MAX_SIZE) == 0) return i; } From e77049e4165c73f7ad9974ddcf9133be9b886924 Mon Sep 17 00:00:00 2001 From: Fatih20 Date: Sat, 29 Apr 2023 16:23:26 +0700 Subject: [PATCH 071/101] Use rmr and cpr command instead. --- src/user-shell.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index cb8581c..39b5564 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -24,8 +24,8 @@ const char command_list[COMMAND_COUNT][COMMAND_MAX_SIZE] = { "rm\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "mv\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "whereis\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", - "rm -r\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", - "cp -r\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + "rmr\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + "cpr\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", }; From 935b6a1649bab05e76c6859109e687bc3e69f857 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Sat, 29 Apr 2023 16:29:37 +0700 Subject: [PATCH 072/101] refactor: add constants --- src/user-shell.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index 7d052ff..7c38cf7 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -11,7 +11,7 @@ #define INDEXES_MAX_COUNT SHELL_BUFFER_SIZE #define PATH_MAX_COUNT 64 #define MAX_FILE_BUFFER_CLUSTER_SIZE 512 // take arbitrary size of 512 cluster = 512 * 4 * 512 B = 1MB - +#define MAX_FOLDER_CLUSTER_SIZE 5 #define EMPTY_EXTENSION "\0\0\0" #define EMPTY_NAME "\0\0\0\0\0\0\0\0" @@ -313,14 +313,14 @@ uint8_t cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory return 0; } - struct ClusterBuffer cl[5]; + struct ClusterBuffer cl[MAX_FOLDER_CLUSTER_SIZE]; struct FAT32DriverRequest request = { .buf = &cl, .name = "root\0\0\0\0", .ext = "\0\0\0", .parent_cluster_number = temp_info.current_cluster_number, - .buffer_size = CLUSTER_SIZE * 5, + .buffer_size = CLUSTER_SIZE * MAX_FOLDER_CLUSTER_SIZE, }; struct FAT32DirectoryTable *dir_table; @@ -412,13 +412,13 @@ void ls_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf return; } - struct ClusterBuffer cl[5]; + struct ClusterBuffer cl[MAX_FOLDER_CLUSTER_SIZE]; struct FAT32DriverRequest request = { .buf = &cl, .name = "root\0\0\0\0", .ext = "\0\0\0", .parent_cluster_number = temp_info.current_cluster_number, - .buffer_size = CLUSTER_SIZE * 5, + .buffer_size = CLUSTER_SIZE * MAX_FOLDER_CLUSTER_SIZE, }; if (temp_info.current_path_count > 0) @@ -612,11 +612,11 @@ void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryIn return; // read the file from FATtable - struct ClusterBuffer cl[255]; + struct ClusterBuffer cl[MAX_FILE_BUFFER_CLUSTER_SIZE]; struct FAT32DriverRequest read_request = { .buf = &cl, .parent_cluster_number = target_directory.current_cluster_number, - .buffer_size = CLUSTER_SIZE * 5, + .buffer_size = CLUSTER_SIZE * MAX_FILE_BUFFER_CLUSTER_SIZE, }; struct ParseString target_filename = {}; @@ -1038,7 +1038,6 @@ int main(void) else if (commandNumber == 6) { // mv_command - struct CurrentDirectoryInfo source_dir = {}; struct CurrentDirectoryInfo dest_dir = {}; @@ -1061,10 +1060,6 @@ int main(void) else if (commandNumber == 7) { } - - else if (commandNumber == 8) - { - } } if (current_directory_info.current_cluster_number) From 099cb1aa214d92e4b6870d5a8dc1e243db28dc86 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Sat, 29 Apr 2023 16:52:08 +0700 Subject: [PATCH 073/101] feat: add argument count checking --- src/user-shell.c | 88 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 68 insertions(+), 20 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index 7c38cf7..5ba7e53 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -884,6 +884,7 @@ int main(void) struct IndexInfo word_indexes[INDEXES_MAX_COUNT]; char too_many_args_msg[] = "Too many arguments\n"; + char missing_args_msg[] = "Missing argument(s)\n"; struct CurrentDirectoryInfo current_directory_info = { @@ -1001,38 +1002,85 @@ int main(void) else if (commandNumber == 4) { // cp_command - struct CurrentDirectoryInfo source_dir = { - .current_cluster_number = current_directory_info.current_cluster_number}; - struct CurrentDirectoryInfo dest_dir = { - .current_cluster_number = current_directory_info.current_cluster_number}; - struct ParseString source_name; - struct ParseString dest_name; + if (argsCount < 3) + { + syscall(5, (uint32_t)missing_args_msg, 21, 0xF); + } - // get source directory info & source file name - invoke_cd(buf, word_indexes+1, &source_dir, &source_name); + else if (argsCount == 3) + { - // get destination directory info & source file name - invoke_cd(buf, word_indexes+2, &dest_dir, &dest_name); + struct CurrentDirectoryInfo source_dir = { + .current_cluster_number = current_directory_info.current_cluster_number}; + struct CurrentDirectoryInfo dest_dir = { + .current_cluster_number = current_directory_info.current_cluster_number}; + + struct ParseString source_name; + struct ParseString dest_name; + + // get source directory info & source file name + invoke_cd(buf, word_indexes+1, &source_dir, &source_name); + + // get destination directory info & source file name + invoke_cd(buf, word_indexes+2, &dest_dir, &dest_name); - // invoke cp command - cp_command(&source_dir, &source_name, &dest_dir, &dest_name); + // invoke cp command + cp_command(&source_dir, &source_name, &dest_dir, &dest_name); + } + + else + { + syscall(5, (uint32_t)too_many_args_msg, 20, 0xF); + } } else if (commandNumber == 5) { // rm_command - struct CurrentDirectoryInfo target_dir; - copy_directory_info(&target_dir,¤t_directory_info); - struct ParseString target_name = {}; - reset_buffer(target_name.word, SHELL_BUFFER_SIZE); + if (argsCount < 2) + { + syscall(5, (uint32_t)missing_args_msg, 21, 0xF); + } - // get source directory info & source file name - invoke_cd(buf, word_indexes+1, &target_dir, &target_name); + else + { + bool isFlagFound = FALSE; + + if (argsCount == 2) + { + if (isFlagFound) + { + syscall(5, (uint32_t)missing_args_msg, 21, 0xF); + } + + else + { + struct CurrentDirectoryInfo target_dir; + copy_directory_info(&target_dir,¤t_directory_info); + + struct ParseString target_name = {}; + reset_buffer(target_name.word, SHELL_BUFFER_SIZE); + + // get source directory info & source file name + invoke_cd(buf, word_indexes+1, &target_dir, &target_name); - // invoke rm command - rm_command(&target_dir, &target_name); + // invoke rm command + rm_command(&target_dir, &target_name); + } + } + + else if (argsCount == 3) + { + + } + + else + { + syscall(5, (uint32_t)too_many_args_msg, 20, 0xF); + } + } } else if (commandNumber == 6) From 4a4e6d6bfbcf684414ab904507856d69846808c5 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Sat, 29 Apr 2023 17:18:25 +0700 Subject: [PATCH 074/101] fix: cd and ls table iteration --- src/user-shell.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index 5ba7e53..be7549c 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -10,7 +10,7 @@ #define EXTENSION_NAME_LENGTH 3 #define INDEXES_MAX_COUNT SHELL_BUFFER_SIZE #define PATH_MAX_COUNT 64 -#define MAX_FILE_BUFFER_CLUSTER_SIZE 512 // take arbitrary size of 512 cluster = 512 * 4 * 512 B = 1MB +#define MAX_FILE_BUFFER_CLUSTER_SIZE 1 // take arbitrary size of 512 cluster = 512 * 4 * 512 B = 1MB #define MAX_FOLDER_CLUSTER_SIZE 5 #define EMPTY_EXTENSION "\0\0\0" #define EMPTY_NAME "\0\0\0\0\0\0\0\0" @@ -346,12 +346,12 @@ uint8_t cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory while (j < dir_table->table->filesize / CLUSTER_SIZE && !found) { - int k = 1; - - while (k < dir_table[j].table->n_of_entries && !found) + for (int k = 1; k < CLUSTER_SIZE / (int) sizeof(struct FAT32DirectoryEntry) && !found; k++) { struct FAT32DirectoryEntry *entry = &dir_table[j].table[k]; + if (entry->user_attribute != UATTR_NOT_EMPTY) continue; + char name[DIRECTORY_NAME_LENGTH] = "\0\0\0\0\0\0\0\0"; memcpy(name, buf + param_indexes[i].index, param_indexes[i].length); @@ -371,8 +371,6 @@ uint8_t cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory temp_info.current_path_count++; found = TRUE; } - - k++; } j++; @@ -444,9 +442,10 @@ void ls_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf while (i < dir_table_count) { - int j = 1; - while (j < dirTable[i].table->n_of_entries) + for (int j = 1; j < CLUSTER_SIZE / (int) sizeof(struct FAT32DirectoryEntry); j++) { + if (dirTable[i].table[j].user_attribute != UATTR_NOT_EMPTY) continue; + uint32_t color; if (dirTable[i].table[j].attribute == ATTR_SUBDIRECTORY) @@ -462,9 +461,7 @@ void ls_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf syscall(5, (uint32_t)dirTable[i].table[j].ext, 3, color); } - if (j < dirTable[i].table->n_of_entries - 1 || i < dir_table_count - 1) - print_space(); - j++; + print_space(); } i++; @@ -851,7 +848,7 @@ int8_t rm_command(struct CurrentDirectoryInfo *file_dir, struct ParseString *fil // create delete request struct FAT32DriverRequest delete_request = { - // .name = EMPTY_NAME, + .name = EMPTY_NAME, .ext = EMPTY_EXTENSION, .parent_cluster_number = file_dir->current_cluster_number, }; @@ -1073,7 +1070,7 @@ int main(void) else if (argsCount == 3) { - + } else From fa69ddb48a13c1417f52c66e005b4286ca910784 Mon Sep 17 00:00:00 2001 From: sozyGithub Date: Sat, 29 Apr 2023 17:21:19 +0700 Subject: [PATCH 075/101] fix: retcode type --- src/user-shell.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index 10fe999..bd76a27 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -586,7 +586,7 @@ void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory memcpy(write_request.name, target_name.word, target_name.length); - int32_t retcode; + int8_t retcode; syscall(2, (uint32_t)&write_request, (uint32_t)&retcode, 0); if (retcode == 1) @@ -656,7 +656,7 @@ void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryIn memcpy(read_request.name, target_file_name_parsed.word, target_file_name_parsed.length); memcpy(read_request.ext, target_file_name_extension.word, target_file_name_extension.length); - int32_t retcode; + int8_t retcode; syscall(0, (uint32_t)&read_request, (uint32_t)&retcode, 0); @@ -713,7 +713,7 @@ uint32_t traverse_directories(char *target_name, uint32_t parent_cluster_number) memcpy(read_folder_request.name, target_name, sizeof(target_name)); - int32_t retcode; + int8_t retcode; syscall(1, (uint32_t)&read_folder_request, (uint32_t)&retcode, 0); if (retcode == 0) From f1231ea1389881444102d36ab869e1974a3ef83f Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Sat, 29 Apr 2023 17:36:39 +0700 Subject: [PATCH 076/101] refactor: change message --- src/user-shell.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index 5bb5105..c4a11bf 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -645,7 +645,7 @@ void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryIn if (split_result != 0 && split_result != 1) { - syscall(5, (uint32_t) "Invalid command!", 16, 0xF); + syscall(5, (uint32_t) "Invalid command.", 16, 0xF); print_newline(); return; } @@ -1129,12 +1129,12 @@ int main(void) // mv_command if (argsCount == 1) { - syscall(5, (uint32_t) "Please give the source and destination path!", 44, 0xF); + syscall(5, (uint32_t) "Please give the source and destination path.", 44, 0xF); print_newline(); } else if (argsCount == 2) { - syscall(5, (uint32_t) "Please give the destination path!", 33, 0xF); + syscall(5, (uint32_t) "Please give the destination path.", 33, 0xF); print_newline(); } else if (argsCount == 3) From 8881c03ed7fd270fdb25f27689846a98cb0e0760 Mon Sep 17 00:00:00 2001 From: Fatih20 Date: Sat, 29 Apr 2023 18:13:58 +0700 Subject: [PATCH 077/101] Recursive delete working. --- src/fat32.c | 10 +++++++++- src/user-shell.c | 19 +++++++------------ 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/fat32.c b/src/fat32.c index 680100a..abba46c 100644 --- a/src/fat32.c +++ b/src/fat32.c @@ -571,6 +571,8 @@ int8_t delete(struct FAT32DriverRequest request, bool is_recursive, bool check_r return 0; } + uint16_t entry_cluster_position = entry->cluster_low; + // If check recursion is false, no checking will be done if (check_recursion && !is_below_max_recursion_depth(entry->cluster_low, 0)) { @@ -578,7 +580,7 @@ int8_t delete(struct FAT32DriverRequest request, bool is_recursive, bool check_r } // Delete the directory's content - delete_subdirectory_content(entry->cluster_low); + delete_subdirectory_content(entry_cluster_position); // Reset the read clusters to the cluster where the entry of the directory to be deleted is located in the directory table read_clusters(&driver_state.dir_table_buf, request.parent_cluster_number, 1); @@ -668,8 +670,14 @@ void delete_subdirectory_content(uint16_t target_cluster_number) i++) { entry = &(driver_state.dir_table_buf.table[i]); + // Skip entry if it's empty + if (is_entry_empty(entry)) + { + continue; + } if (is_subdirectory(entry)) { + memcpy(&(req.name), &(entry->name), 8); delete (req, TRUE, FALSE); } else diff --git a/src/user-shell.c b/src/user-shell.c index 59b16cb..98c8e4c 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -24,7 +24,7 @@ const char command_list[COMMAND_COUNT][COMMAND_MAX_SIZE] = { "rm\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "mv\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "whereis\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", - "rmr\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + "rmr\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "cpr\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", @@ -833,7 +833,7 @@ uint8_t cp_command(struct CurrentDirectoryInfo *source_dir, * @param is_recursive whether the rm command should be recursive * @return - */ -void rm_command(struct CurrentDirectoryInfo *file_dir, struct ParseString *file_name, bool is_recursive) +int8_t rm_command(struct CurrentDirectoryInfo *file_dir, struct ParseString *file_name, bool is_recursive) { struct ParseString name; struct ParseString ext; @@ -1057,8 +1057,10 @@ int main(void) // invoke mv command mv_command(&source_dir, &source_name, &dest_dir, &dest_name); } - else if (commandNumber == 7) + { + } + else if (commandNumber == 8) { // rm recursive command struct CurrentDirectoryInfo target_dir = current_directory_info; @@ -1066,18 +1068,11 @@ int main(void) struct ParseString target_name; // get source directory info & source file name - struct IndexInfo new_path_indexes[INDEXES_MAX_COUNT]; - parse_path_for_cd(buf, word_indexes, new_path_indexes); - invoke_cd(buf, new_path_indexes, &target_dir, &target_name); + invoke_cd(buf, word_indexes + 1, &target_dir, &target_name); - // invoke rm recursive command + // invoke cp command rm_command(&target_dir, &target_name, TRUE); } - - else if (commandNumber == 8) - { - // cp recursive command - } } if (current_directory_info.current_cluster_number) From abb8ad65d1e607af913da526734f1f71ae68543d Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Sat, 29 Apr 2023 18:25:04 +0700 Subject: [PATCH 078/101] feat: retcode checking --- src/kernel.c | 6 ++-- src/user-shell.c | 88 +++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 75 insertions(+), 19 deletions(-) diff --git a/src/kernel.c b/src/kernel.c index 768a83a..9962004 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -42,7 +42,7 @@ void kernel_setup(void) write(req); // move parent to f1 - req.parent_cluster_number = 0xa; + req.parent_cluster_number = 0xb; memcpy(req.name, "f4", 2); write(req); @@ -51,12 +51,12 @@ void kernel_setup(void) write(req); // move parent to f1 - req.parent_cluster_number = 0xd; + req.parent_cluster_number = 0xe; memcpy(req.name, "f6", 2); write(req); - req.parent_cluster_number = 0xf; + req.parent_cluster_number = 0x10; memcpy(req.name, "f7", 2); write(req); diff --git a/src/user-shell.c b/src/user-shell.c index c4a11bf..c691feb 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -805,10 +805,9 @@ uint8_t cp_command(struct CurrentDirectoryInfo *source_dir, splitcode = split_filename_extension(source_name, &name, &ext); if (splitcode == 2 || splitcode == 3) { - char msg[] = "Source file not found!\n"; + char msg[] = "Source file not found.\n"; syscall(5, (uint32_t)msg, 24, 0xF); - - // return; + return 1; } // prepare read file request @@ -835,7 +834,7 @@ uint8_t cp_command(struct CurrentDirectoryInfo *source_dir, splitcode = split_filename_extension(dest_name, &name, &ext); if (splitcode == 2 || splitcode == 3) { - char msg[] = "Source file not found!\n"; + char msg[] = "Source file not found.\n"; syscall(5, (uint32_t)msg, 24, 0xF); // return; } @@ -853,14 +852,53 @@ uint8_t cp_command(struct CurrentDirectoryInfo *source_dir, // copy file from memory to disk syscall(2, (uint32_t)&write_request, (uint32_t)&retcode, 0); + if (retcode) { + if (retcode == 1) + { + char msg[] = "File/folder already exists.\n"; + syscall(5, (uint32_t)msg, 29, 0xF); + } + + else if (retcode == 3) + { + char msg[] = "Forbidden file/folder name.\n"; + syscall(5, (uint32_t)msg, 29, 0xF); + } + + else + { + char msg[] = "Unknown error.\n"; + syscall(5, (uint32_t)msg, 16, 0xF); + } + return 2; } } + else { - // try read folder + if (retcode == 2) + { + char msg[] = "Not enough buffer.\n"; + syscall(5, (uint32_t)msg, 20, 0xF); + } + + else if (retcode == -1) + { + char msg[] = "Unknown error.\n"; + syscall(5, (uint32_t)msg, 16, 0xF); + } + + else + { + char msg[] = "Source file not found.\n"; + syscall(5, (uint32_t)msg, 24, 0xF); + } + + return 1; } + return 0; } @@ -881,7 +919,7 @@ int8_t rm_command(struct CurrentDirectoryInfo *file_dir, struct ParseString *fil splitcode = split_filename_extension(file_name, &name, &ext); if (splitcode == 2 || splitcode == 3) { - char msg[] = "Source file not found!\n"; + char msg[] = "Source file not found.\n"; syscall(5, (uint32_t)msg, 24, 0xF); return 1; } @@ -896,8 +934,31 @@ int8_t rm_command(struct CurrentDirectoryInfo *file_dir, struct ParseString *fil memcpy(delete_request.ext, ext.word, ext.length); int8_t retcode; + syscall(3, (uint32_t)&delete_request, (uint32_t)&retcode, 0); + if (retcode != 0) + { + if (retcode == 2) + { + char msg[] = "Folder is not empty.\n"; + syscall(5, (uint32_t)msg, 22, 0xF); + } + + else if (retcode == -1) + { + char msg[] = "Unknown error.\n"; + syscall(5, (uint32_t)msg, 16, 0xF); + } + + else + { + char msg[] = "File/folder not found.\n"; + syscall(5, (uint32_t)msg, 24, 0xF); + } + + } + return retcode; } @@ -906,12 +967,12 @@ void mv_command(struct CurrentDirectoryInfo *source_dir, struct CurrentDirectoryInfo *dest_dir, struct ParseString *dest_name) { - cp_command(source_dir, + uint8_t res = cp_command(source_dir, source_name, dest_dir, dest_name); - rm_command(source_dir, source_name); + if (res == 0) rm_command(source_dir, source_name); } int main(void) @@ -971,13 +1032,12 @@ int main(void) if (commandNumber == -1) { - char msg[] = "Command not found!\n"; + char msg[] = "Command not found.\n"; syscall(5, (uint32_t)msg, 19, 0xF); } else { - if (commandNumber == 0) { if (argsCount == 1) @@ -1008,7 +1068,7 @@ int main(void) { if (argsCount == 1) { - syscall(5, (uint32_t) "Please give the folder path and name!\n", 39, 0xF); + syscall(5, (uint32_t) "Please give the folder path and name.\n", 39, 0xF); print_newline(); } else if (argsCount == 2) @@ -1026,7 +1086,7 @@ int main(void) { if (argsCount == 1) { - syscall(5, (uint32_t) "Please give the file path and name!\n", 39, 0xF); + syscall(5, (uint32_t) "Please give the file path and name.\n", 39, 0xF); print_newline(); } else if (argsCount == 2) @@ -1167,10 +1227,6 @@ int main(void) { } } - - if (current_directory_info.current_cluster_number) - { - } } } From 668cd3c998b235d0c83dd37537cbd78c2580b6ef Mon Sep 17 00:00:00 2001 From: maikeljh Date: Sat, 29 Apr 2023 18:26:50 +0700 Subject: [PATCH 079/101] feat: create B+ Tree, syscall7, whereis command --- makefile | 3 +- src/bplustree.c | 427 +++++++++++++++++++++++++++++++++++++ src/fat32.c | 63 +----- src/interrupt.c | 15 ++ src/kernel.c | 25 ++- src/lib-header/bplustree.h | 190 +++++++++++++++++ src/lib-header/fat32.h | 2 + src/user-shell.c | 147 ++++++++----- 8 files changed, 749 insertions(+), 123 deletions(-) create mode 100644 src/bplustree.c create mode 100644 src/lib-header/bplustree.h diff --git a/makefile b/makefile index a1d373e..7cfc3cc 100644 --- a/makefile +++ b/makefile @@ -42,6 +42,7 @@ kernel: $(CC) $(CFLAGS) $(SOURCE_FOLDER)/keyboard.c -o $(OUTPUT_FOLDER)/keyboard.o $(CC) $(CFLAGS) $(SOURCE_FOLDER)/kernel.c -o $(OUTPUT_FOLDER)/kernel.o $(CC) $(CFLAGS) $(SOURCE_FOLDER)/fat32.c -o $(OUTPUT_FOLDER)/fat32.o + $(CC) $(CFLAGS) $(SOURCE_FOLDER)/bplustree.c -o $(OUTPUT_FOLDER)/bplustree.o $(CC) $(CFLAGS) $(SOURCE_FOLDER)/disk.c -o $(OUTPUT_FOLDER)/disk.o $(CC) $(CFLAGS) $(SOURCE_FOLDER)/cmosrtc.c -o $(OUTPUT_FOLDER)/cmosrtc.o $(CC) $(CFLAGS) $(SOURCE_FOLDER)/paging.c -o $(OUTPUT_FOLDER)/paging.o @@ -72,7 +73,7 @@ disk: inserter: @$(CC) -Wno-builtin-declaration-mismatch -g \ - $(SOURCE_FOLDER)/stdmem.c $(SOURCE_FOLDER)/fat32.c $(SOURCE_FOLDER)/cmosrtc.c $(SOURCE_FOLDER)/portio.c \ + $(SOURCE_FOLDER)/stdmem.c $(SOURCE_FOLDER)/fat32.c $(SOURCE_FOLDER)/bplustree.c $(SOURCE_FOLDER)/cmosrtc.c $(SOURCE_FOLDER)/portio.c \ $(SOURCE_FOLDER)/external-inserter.c \ -o $(OUTPUT_FOLDER)/inserter diff --git a/src/bplustree.c b/src/bplustree.c new file mode 100644 index 0000000..e23ac8e --- /dev/null +++ b/src/bplustree.c @@ -0,0 +1,427 @@ +#include "lib-header/bplustree.h" +#include "lib-header/stdmem.h" + +/* B+ Tree */ +static struct NodeFileSystem nodes[MAX_NODES]; // Static buffer to hold nodes +static uint32_t node_index = 0; // Current index in the buffer nodes + +static struct PCNode pcNodes[MAX_NODES]; // Static buffer to hold PCNodes +static uint32_t pc_node_index = 0; // Current index in the buffer PCNodes + +struct NodeFileSystem *make_tree(char *file_name, char* ext, uint32_t parent_cluster_number){ + // Malloc new leaf + struct NodeFileSystem *newTree = make_leaf(); + + // Copy filename to key + memcpy(newTree->keys[0], file_name, 8); + + // Create new PCNode + newTree->children[0] = make_pcnode(parent_cluster_number, ext); + + // Set parent to NULL + newTree->parent = NULL; + + // Increment number of keys + newTree->number_of_keys++; + + return newTree; +} + +struct PCNode *make_pcnode(uint32_t parent_cluster_number, char *ext){ + // Create a new Parent Cluster Node + struct PCNode *node = &pcNodes[pc_node_index]; + pc_node_index++; + + // Insert parent_cluster_number and extension + node->parent_cluster_number[0] = parent_cluster_number; + node->n_of_items = 1; + memcpy(node->ext[0], ext, 3); + + return node; +} + +struct NodeFileSystem *make_node(){ + // Create a new node + struct NodeFileSystem *node = &nodes[node_index]; + node_index++; + + // Initialize node's attributes + node->leaf = FALSE; + node->number_of_keys = 0; + node->parent = NULL; + + return node; +} + +struct NodeFileSystem *make_leaf(){ + // Create a new leaf (leaf == TRUE) + struct NodeFileSystem *node = make_node(); + node->leaf = TRUE; + + return node; +} + +struct PCNode *find_pcn(struct NodeFileSystem *root, char* file_name){ + // Find leaf node that contains key = file_name + struct NodeFileSystem *leaf = find_leaf(root, file_name); + + // Find key to return PCNode + uint32_t i = 0; + for(i = 0; i < leaf->number_of_keys; i++){ + if(memcmp(leaf->keys[i], file_name, 8) == 0){ + break; + } + } + + // If key not found (file_name not found) + if(i == leaf->number_of_keys){ + return NULL; + } else { + // Return PCNode + return (struct PCNode *) leaf->children[i]; + } +} + +struct NodeFileSystem *find_leaf(struct NodeFileSystem *root, char *file_name){ + // Find leaf by iterating nodes with key = file_name + uint32_t i; + struct NodeFileSystem *temp = root; + + // While node != leaf + while(!temp->leaf){ + // Iterate all keys + i = 0; + while(i < temp->number_of_keys){ + if(memcmp(file_name, temp->keys[i], 8) >= 0){ + i++; + } else { + // Key found + break; + } + } + // Iterate until leaf found + temp = (struct NodeFileSystem *) temp->children[i]; + } + + return temp; +} + +struct NodeFileSystem *insert(struct NodeFileSystem *root, char *file_name, char *ext, uint32_t parent_cluster_number){ + // Make new PCNode + struct PCNode *newPCN = NULL; + + // Search if key already exists + newPCN = find_pcn(root, file_name); + if(newPCN != NULL){ + return insert_another_pcn(root, newPCN, parent_cluster_number, ext); + } + + // Create new PCNode + newPCN = make_pcnode(parent_cluster_number, ext); + + // Find leaf + struct NodeFileSystem *leaf = find_leaf(root, file_name); + + // Check if leaf need to be splitted (balancing) + if(leaf->number_of_keys < MAX_CHILDREN - 1){ + return insert_into_leaf(root, leaf, file_name, newPCN); + } + + return insert_into_leaf_after_splitting(root, leaf, file_name, newPCN); +} + +struct NodeFileSystem *insert_into_leaf(struct NodeFileSystem *root, struct NodeFileSystem *leaf, char *file_name, struct PCNode *newPCN){ + // Find key in leaf + uint32_t i; + uint32_t newIdx = 0; + + while(newIdx < leaf->number_of_keys && memcmp(leaf->keys[newIdx], file_name, 8) == -1){ + newIdx++; + } + + // Shift keys to right to assign the file_name in the correct order (B+ Tree must be sorted!) + for(i = leaf->number_of_keys; i > newIdx; i--){ + memcpy(leaf->keys[i], leaf->keys[i-1], 8); + leaf->children[i] = leaf->children[i-1]; + } + + // Assign new key + memcpy(leaf->keys[newIdx], file_name, 8); + + // Assign PCNode to leaf + leaf->children[newIdx] = newPCN; + + // Increment number of keys + leaf->number_of_keys++; + + return root; +} + +struct NodeFileSystem *insert_another_pcn(struct NodeFileSystem *root, struct PCNode *node, uint32_t parent_cluster_number, char *ext){ + // Insert another target with the same target name + memcpy(node->ext[node->n_of_items], ext, 3); + node->parent_cluster_number[node->n_of_items] = parent_cluster_number; + node->n_of_items++; + + return root; +} + +struct NodeFileSystem *insert_into_leaf_after_splitting(struct NodeFileSystem *root, struct NodeFileSystem *leaf, char *file_name, struct PCNode *newPCN){ + // Create new leaf and temporary attributes + struct NodeFileSystem *new_leaf = make_leaf(); + char keys[MAX_CHILDREN][8]; + void *children[MAX_CHILDREN + 1]; + uint32_t newIdx, split, i , j; + char new_key[8]; + + // Iterate through all keys to find index to split + newIdx = 0; + while(newIdx < MAX_CHILDREN - 1 && memcmp(leaf->keys[newIdx], file_name, 8) == -1) { + newIdx++; + } + + // Assign leaf keys to temporary + for(i = 0, j = 0; i < leaf->number_of_keys; i++, j++){ + if(j == newIdx){ + // Skip index to split + j++; + } + memcpy(keys[j], leaf->keys[i], 8); + children[j] = leaf->children[i]; + } + + // Assign new key and new PCN to new index + memcpy(keys[newIdx], file_name, 8); + children[newIdx] = newPCN; + + // Reset number of keys + leaf->number_of_keys = 0; + + // Find index to split + split = ceil(MAX_CHILDREN - 1, 2); + + // Make left leaf + for(i = 0; i < split; i++){ + leaf->children[i] = children[i]; + memcpy(leaf->keys[i], keys[i], 8); + leaf->number_of_keys++; + } + + // Make right leaf + for(i = split, j = 0; i < MAX_CHILDREN; i++, j++){ + new_leaf->children[j] = children[i]; + memcpy(new_leaf->keys[j], keys[i], 8); + new_leaf->number_of_keys++; + } + + // Make pointer from left to right node and right node to itself + new_leaf->children[MAX_CHILDREN - 1] = leaf->children[MAX_CHILDREN - 1]; + leaf->children[MAX_CHILDREN - 1] = new_leaf; + + // Remove children that have no keys + for(i = leaf->number_of_keys; i < MAX_CHILDREN - 1; i++){ + leaf->children[i] = NULL; + } + + for(i = new_leaf->number_of_keys; i < MAX_CHILDREN - 1; i++){ + new_leaf->children[i] = NULL; + } + + // Assign new leaf parent + new_leaf->parent = leaf->parent; + memcpy(new_key, new_leaf->keys[0], 8); + + // Insert into parent after splitting + return insert_into_parent(root, leaf, new_key, new_leaf); +} + +struct NodeFileSystem *insert_into_parent(struct NodeFileSystem *root, struct NodeFileSystem *left, char *file_name, struct NodeFileSystem *right){ + uint32_t left_index; + struct NodeFileSystem *parent; + + // Get parent from left node + parent = left->parent; + + // If no parent found + if (parent == NULL){ + // Create new root + return insert_into_new_root(left, file_name, right); + } + + // Get left index of left node from parent + left_index = get_left_index(parent, left); + + // Check if node needs to be splitted (balancing) + if (parent->number_of_keys < MAX_CHILDREN - 1){ + return insert_into_node(root, parent, left_index, file_name, right); + } + + return insert_into_node_after_splitting(root, parent, left_index, file_name, right); +} + +struct NodeFileSystem *insert_into_new_root(struct NodeFileSystem *left, char *file_name, struct NodeFileSystem *right){ + // Create a new root node + struct NodeFileSystem *newRoot = make_node(); + + // Assign values to root's attributes + memcpy(newRoot->keys[0], file_name, 8); + newRoot->children[0] = left; + newRoot->children[1] = right; + newRoot->number_of_keys++; + newRoot->parent = NULL; + + // Assign left and right node parent to new root + left->parent = newRoot; + right->parent = newRoot; + + return newRoot; +} + +struct NodeFileSystem *insert_into_node(struct NodeFileSystem *root, struct NodeFileSystem *n, uint32_t left_index, char *file_name, struct NodeFileSystem *right){ + // Shift right keys and childrens to insert new key + uint32_t i; + for(i = n->number_of_keys; i > left_index; i--){ + n->children[i+1] = n->children[i]; + memcpy(n->keys[i], n->keys[i-1], 8); + } + + // Insert new children to the correct position (must be ordered!) + n->children[left_index + 1] = right; + + // Assign key to the correct position + memcpy(n->keys[left_index], file_name, 8); + + // Increment number of keys + n->number_of_keys++; + + return root; +} + +struct NodeFileSystem *insert_into_node_after_splitting(struct NodeFileSystem *root, struct NodeFileSystem *old_node, uint32_t left_index, char *file_name, struct NodeFileSystem *right){ + // Create new node and temporary attributes + uint32_t i, j, split; + struct NodeFileSystem *new_node, *child; + char keys[MAX_CHILDREN][8], k_prime[8]; + void *children[MAX_CHILDREN + 1]; + + // Assign old children to temporary children + for (i = 0, j = 0; i < old_node->number_of_keys + 1; i++, j++) { + if (j == left_index + 1){ + j++; + } + children[j] = old_node->children[i]; + } + + // Assign old keys to temporary keys + for (i = 0, j = 0; i < old_node->number_of_keys; i++, j++) { + if (j == left_index){ + j++; + } + memcpy(keys[j], old_node->keys[i], 8); + } + + // Assign new key and children + children[left_index + 1] = right; + memcpy(keys[left_index], file_name, 8); + + // Find split index + split = ceil(MAX_CHILDREN, 2); + + // Create new node + new_node = make_node(); + + // Reset old node + old_node->number_of_keys = 0; + + // Split to left node + for (i = 0; i < split - 1; i++) { + old_node->children[i] = children[i]; + memcpy(old_node->keys[i], keys[i], 8); + old_node->number_of_keys++; + } + + // Assign children and key prime + old_node->children[i] = children[i]; + memcpy(k_prime, keys[split - 1], 8); + i++; + + // Split to right node + for (j = 0; i < MAX_CHILDREN; i++, j++) { + new_node->children[j] = children[i]; + memcpy(new_node->keys[j], keys[i], 8); + new_node->number_of_keys++; + } + + // Assign children and parent + new_node->children[j] = children[i]; + new_node->parent = old_node->parent; + + // Assign child's parent to new node + for (i = 0; i <= new_node->number_of_keys; i++) { + child = new_node->children[i]; + child->parent = new_node; + } + + // Insert into parent after splitting + return insert_into_parent(root, old_node, k_prime, new_node); +} + +uint32_t get_left_index(struct NodeFileSystem *parent, struct NodeFileSystem *left){ + // Iterate all keys and children of parent to find the left node + uint32_t left_index = 0; + while(left_index <= parent->number_of_keys && parent->children[left_index] != left){ + left_index++; + } + + // Return index of left node + return left_index; +} + +void initialize_b_tree(struct NodeFileSystem *root, char *dir_name, uint32_t parent_cluster_number, uint32_t dir_cluster_number){ + struct FAT32DirectoryTable dir_table[10]; + struct FAT32DriverRequest read_folder_request = { + .buf = dir_table, + .ext = "\0\0\0", + .parent_cluster_number = parent_cluster_number, + .buffer_size = sizeof(struct FAT32DirectoryTable) * 10, + }; + memcpy(read_folder_request.name, dir_name, 8); + int tes = read_directory(read_folder_request); + if(tes){} + for (uint32_t i = 0; i < 10; i++) + { + uint32_t counter_entry = 0; + for (uint32_t j = 1; j < CLUSTER_SIZE / sizeof(struct FAT32DirectoryEntry) && counter_entry < dir_table[0].table[0].n_of_entries; j++) + { + counter_entry++; + if (dir_table[i].table[j].attribute == ATTR_SUBDIRECTORY) + { + BPlusTree = insert(root, dir_table[i].table[j].name, dir_table[i].table[j].ext, dir_cluster_number); + root = BPlusTree; + if(memcmp(dir_name, "root\0\0\0\0", 8) == 0){ + initialize_b_tree(BPlusTree, dir_table[i].table[j].name, (dir_table[i].table[0].cluster_high << 16) + dir_table[i].table[0].cluster_low, (dir_table[i].table[j].cluster_high << 16) + dir_table[i].table[j].cluster_low); + } else { + initialize_b_tree(BPlusTree, dir_table[i].table[j].name, dir_cluster_number, (dir_table[i].table[j].cluster_high << 16) + dir_table[i].table[j].cluster_low); + } + } + else if (!is_entry_empty(&dir_table[i].table[j])) + { + insert(root, dir_table[i].table[j].name, dir_table[i].table[j].ext, dir_cluster_number); + } + } + } +} + +uint8_t whereis_main(struct RequestSearch *request){ + // Find PCNode that has target name + struct PCNode *result = find_pcn(BPlusTree, request->search); + + // If no target found + if(result == NULL){ + return 0; + } else { + // Target found + request->result = *result; + return 1; + } +} \ No newline at end of file diff --git a/src/fat32.c b/src/fat32.c index 6c1a65b..360df70 100644 --- a/src/fat32.c +++ b/src/fat32.c @@ -89,6 +89,7 @@ const uint8_t fs_signature[BLOCK_SIZE] = { static struct FAT32DriverState driver_state; static char empty_cluster_value[CLUSTER_SIZE]; +struct NodeFileSystem *BPlusTree; uint32_t cluster_to_lba(uint32_t cluster) { return cluster * CLUSTER_BLOCK_COUNT + BOOT_SECTOR; @@ -124,6 +125,12 @@ void initialize_filesystem_fat32(void) { // Move the FAT table from storage to the driver state read_clusters(&driver_state.fat_table, 1, 1); + // Initialize B+ Tree + BPlusTree = make_tree("root\0\0\0\0", "\0\0\0", 2); + initialize_b_tree(BPlusTree, "root\0\0\0\0", 2, 2); + + struct NodeFileSystem *tes = BPlusTree; + if(tes->leaf){} // Initialize static array for empty clusters for (int i = 0; i < CLUSTER_SIZE; i++) { empty_cluster_value[i] = 0; @@ -899,58 +906,4 @@ void set_access_datetime(struct FAT32DirectoryEntry *entry) { uint32_t FTTimestamp = get_FTTimestamp_time(); entry->access_date = ((FTTimestamp & 0xFFFF0000) >> 16); entry->access_time = (FTTimestamp & 0x0000FFFF); -} - -// uint32_t read_cluster_number(char** directories, int count, uint16_t latest_parent_cluster_number) { - -// // return ROOT_CLUSTER_NUMBER if not found - -// read_clusters(&driver_state.dir_table_buf, latest_parent_cluster_number, 1); - -// int i = 0; -// struct FAT32DirectoryEntry *entry; -// uint16_t current_cluster_number = latest_parent_cluster_number; - -// // Find every directory table until the last one is found -// while (i < count) -// { -// bool found_matching_directory = FALSE; -// bool end_of_directory = FALSE; -// uint16_t temp_cluster_number = current_cluster_number; - -// while (!end_of_directory && !found_matching_directory) { - -// // Traverse the table in examined cluster. Starts from 1 because the first -// // entry of the table is the directory itself -// for (uint8_t i = 1; i < CLUSTER_SIZE / sizeof(struct FAT32DirectoryEntry) && !found_matching_directory; i++) { -// entry = &(driver_state.dir_table_buf.table[i]); -// found_matching_directory = !is_entry_empty(entry) && (memcmp(entry->name, directories[i], 8) == 0) && is_subdirectory(entry); -// } - -// // If the cluster_number is EOF, then we've finished examining the last -// // cluster of the directory -// end_of_directory = (driver_state.fat_table.cluster_map[temp_cluster_number] & -// 0x0000FFFF) == 0xFFFF; - -// // If directory is found, get out of the loop -// if (found_matching_directory) -// continue; - -// // Move onto the next cluster if it's not the end yet -// if (!end_of_directory) { -// temp_cluster_number = driver_state.fat_table.cluster_map[temp_cluster_number]; -// read_clusters(&driver_state.dir_table_buf, (uint32_t)temp_cluster_number, 1); -// } -// } - -// if (!found_matching_directory) { -// return ROOT_CLUSTER_NUMBER; -// } - -// i++; -// current_cluster_number = entry->cluster_low; -// } - -// return current_cluster_number; - -// } +} \ No newline at end of file diff --git a/src/interrupt.c b/src/interrupt.c index 48a99c0..7273f3c 100644 --- a/src/interrupt.c +++ b/src/interrupt.c @@ -6,6 +6,7 @@ #include "lib-header/idt.h" #include "lib-header/fat32.h" #include "lib-header/stdmem.h" +#include "lib-header/bplustree.h" void io_wait(void) { @@ -186,6 +187,20 @@ void syscall(struct CPURegister cpu, __attribute__((unused)) struct InterruptSta *((int8_t *)cpu.ecx) = 1; } } + + else if (cpu.eax == 7) + { + // Get request from ebx + struct RequestSearch *request = (struct RequestSearch *)cpu.ebx; + + // Execute whereis main + uint8_t res = whereis_main(request); + + // If no target found, set n_of_items to 0 + if(res == 0){ + request->result.n_of_items = 0; + } + } } void main_interrupt_handler(struct CPURegister cpu, uint32_t int_number, struct InterruptStack info) diff --git a/src/kernel.c b/src/kernel.c index ec5b0f8..8dc80fc 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -34,31 +34,40 @@ void kernel_setup(void) { }; write(req); + req.parent_cluster_number = 0xA; memcpy(req.name, "f2", 2); write(req); + req.parent_cluster_number = ROOT_CLUSTER_NUMBER; + req.buffer_size = 10; memcpy(req.name, "f3", 2); + memcpy(req.ext, "jav", 3); write(req); - // move parent to f1 - req.parent_cluster_number = 0x9; - + // move parent to f2 + req.parent_cluster_number = 0xB; + req.buffer_size = 0; + memcpy(req.ext, "\0\0\0", 3); memcpy(req.name, "f4", 2); write(req); + req.parent_cluster_number = 0xD; + req.buffer_size = 10; memcpy(req.name, "f5", 2); + memcpy(req.ext, "jir", 3); write(req); // move parent to f1 - req.parent_cluster_number = 0xc; + req.parent_cluster_number = 0xB; - memcpy(req.name, "f6", 2); + memcpy(req.name, "f4", 2); + memcpy(req.ext, "gob", 3); write(req); - req.parent_cluster_number = 0xe; - memcpy(req.name, "f7", 2); + memcpy(req.name, "f5", 2); + memcpy(req.ext, "tot", 3); write(req); - + // Write shell into memory struct FAT32DriverRequest request = { .buf = (uint8_t*) 0, diff --git a/src/lib-header/bplustree.h b/src/lib-header/bplustree.h new file mode 100644 index 0000000..e447c18 --- /dev/null +++ b/src/lib-header/bplustree.h @@ -0,0 +1,190 @@ +#ifndef _BPLUSTREE_H +#define _BPLUSTREE_H + +#include "stdtype.h" +#include "fat32.h" + +#define MAX_NODES 256 +#define MAX_CHILDREN 5 +#define NULL ((void *)0) + +/* -- B+ Tree -- */ +/** + * @brief Parent Cluster Node, containing parent cluster number of files/folders and the extensions + * @param parent_cluster_number Parent directory cluster number + * @param ext Extensions of each file/folder + * @param n_of_items Number of items (files/folders) + */ +struct PCNode +{ + uint32_t parent_cluster_number[MAX_CHILDREN]; + char ext[MAX_CHILDREN][3]; + uint32_t n_of_items; +}; + +/** + * @brief NodeFileSystem, element of B+ Tree + * @param number_of_keys The amount of all available keys inside a node + * @param children Children of a node (can be NodeFileSystem or PCNode) + * @param parent Parent of a node + * @param leaf Determines if the node is a leaf or not + */ +struct NodeFileSystem +{ + uint32_t number_of_keys; + char keys[MAX_CHILDREN][8]; + void *children[MAX_CHILDREN + 1]; + struct NodeFileSystem *parent; + bool leaf; +}; + +/** + * @brief RequestSearch, To handle whereis request + * @param search the target name + * @param result node containing list of files/folders information to print + */ +struct RequestSearch +{ + char search[8]; + struct PCNode result; +}; + +// B+ Tree +extern struct NodeFileSystem *BPlusTree; + +/** + * @brief Make a new base tree from root + * @param file_name the name of the file/directory + * @param ext the extension of the file/directory + * @param parent_cluster_number the parent cluster number of the root + */ +struct NodeFileSystem *make_tree(char *file_name, char *ext, uint32_t parent_cluster_number); + +/** + * @brief Make a new Parent Cluster Node + * @param parent_cluster_number the parent cluster number of the file/directory + * @param ext the extension of the file/directory + */ +struct PCNode *make_pcnode(uint32_t parent_cluster_number, char *ext); + +/** + * @brief Make a new node + */ +struct NodeFileSystem *make_node(); + +/** + * @brief Make a new leaf (leaf = TRUE) + */ +struct NodeFileSystem *make_leaf(); + +/** + * @brief Find Parent Cluster Node with target name == file_name + * @param root the B+ Tree + * @param file_name the name of the file/directory + */ +struct PCNode *find_pcn(struct NodeFileSystem *root, char* file_name); + +/** + * @brief Find Leaf with target name == file_name + * @param root the B+ Tree + * @param file_name the name of the file/directory + */ +struct NodeFileSystem *find_leaf(struct NodeFileSystem *root, char *file_name); + +/** + * @brief Insert a new file/directory to tree + * @param root the B+ Tree + * @param file_name the name of the file/directory + * @param ext the extension of the file/directory + * @param parent_cluster_number the parent cluster number of the file/directory + */ +struct NodeFileSystem *insert(struct NodeFileSystem *root, char *file_name, char *ext, uint32_t parent_cluster_number); + +/** + * @brief Insert Key and PCNode to Leaf + * @param root the B+ Tree + * @param leaf the Leaf Node + * @param file_name the name of the file/directory + * @param newPCN New PCNode containing parent cluster number and ext of the file/directory + */ +struct NodeFileSystem *insert_into_leaf(struct NodeFileSystem *root, struct NodeFileSystem *leaf, char *file_name, struct PCNode *newPCN); + +/** + * @brief Insert another file/directory information to PCNode with same target's name + * @param root the B+ Tree + * @param node PCNode with the same target's name + * @param parent_cluster_number the parent cluster number of the file/directory + * @param ext the extension of the file/directory + */ +struct NodeFileSystem *insert_another_pcn(struct NodeFileSystem *root, struct PCNode *node, uint32_t parent_cluster_number, char *ext); + +/** + * @brief Insert file/directory information into leaf after splliting the leaf + * @param root the B+ Tree + * @param leaf the Leaf Node + * @param file_name the name of the file/directory + * @param newPCN New PCNode containing parent cluster number and ext of the file/directory + */ +struct NodeFileSystem *insert_into_leaf_after_splitting(struct NodeFileSystem *root, struct NodeFileSystem *leaf, char *file_name, struct PCNode *newPCN); + +/** + * @brief Insert target into parent, if parent == NULL, create a new parent + * @param root the B+ Tree + * @param left the left node + * @param file_name the name of the file/directory + * @param right the right node + */ +struct NodeFileSystem *insert_into_parent(struct NodeFileSystem *root, struct NodeFileSystem *left, char *file_name, struct NodeFileSystem *right); + +/** + * @brief Create a new root of tree with target + * @param left the left node + * @param file_name the name of the file/directory + * @param right the right node + */ +struct NodeFileSystem *insert_into_new_root(struct NodeFileSystem *left, char *file_name, struct NodeFileSystem *right); + +/** + * @brief Insert target into node + * @param root the B+ Tree + * @param n the node that want to be inserted with target + * @param left_index the index of left node + * @param file_name the name of the file/directory + * @param right the right node + */ +struct NodeFileSystem *insert_into_node(struct NodeFileSystem *root, struct NodeFileSystem *n, uint32_t left_index, char *file_name, struct NodeFileSystem *right); + +/** + * @brief Insert target into node after splitting + * @param root the B+ Tree + * @param n the node that want to be inserted with target + * @param left_index the index of left node + * @param file_name the name of the file/directory + * @param right the right node + */ +struct NodeFileSystem *insert_into_node_after_splitting(struct NodeFileSystem *root, struct NodeFileSystem *n, uint32_t left_index, char *file_name, struct NodeFileSystem *right); + +/** + * @brief Get the index of left node + * @param parent the parent node + * @param left the left node + */ +uint32_t get_left_index(struct NodeFileSystem *parent, struct NodeFileSystem *left); + +/** + * @brief Initialize a new B+ Tree from a directory (root) + * @param root the B+ Tree + * @param dir_name the directory name (root) + * @param parent_cluster_number the parent of the directory + * @param dir_cluster_number the cluster number of the directory + */ +void initialize_b_tree(struct NodeFileSystem *root, char* dir_name, uint32_t parent_cluster_number, uint32_t dir_cluster_number); + +/** + * @brief Search target with find_pcn + * @param request RequestSearch containing target's name + * @return 0 if no target found, 1 if target found + */ +uint8_t whereis_main(struct RequestSearch *request); + +#endif diff --git a/src/lib-header/fat32.h b/src/lib-header/fat32.h index c9372f6..0f79945 100644 --- a/src/lib-header/fat32.h +++ b/src/lib-header/fat32.h @@ -4,6 +4,7 @@ #include "disk.h" #include "stdtype.h" #include "cmosrtc.h" +#include "bplustree.h" /** * FAT32 - IF2230 edition - 2023 @@ -82,6 +83,7 @@ struct FAT32FileAllocationTable * @param filesize Filesize of this file, if this is directory / folder, * filesize is the number of cluster it occupies * cluster size */ + struct FAT32DirectoryEntry { char name[8]; diff --git a/src/user-shell.c b/src/user-shell.c index 3459d92..5ea5316 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -2,6 +2,7 @@ #include "lib-header/fat32.h" #include "lib-header/stdmem.h" #include "lib-header/framebuffer.h" +#include "lib-header/bplustree.h" #define SHELL_BUFFER_SIZE 256 #define COMMAND_MAX_SIZE 32 @@ -557,9 +558,9 @@ void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory // temporary CurrentDirectoryInfo for creating the new directory struct CurrentDirectoryInfo target_directory = {}; copy_directory_info(&target_directory, info); - char target_name[target_name_length]; + struct ParseString target_name; - invoke_cd(buf, 6, new_path_indexes, &target_directory, target_name); + invoke_cd(buf, 6, new_path_indexes, &target_directory, &target_name); // create new directory in the target_directory struct ClusterBuffer cl[5]; @@ -570,7 +571,7 @@ void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory .buffer_size = CLUSTER_SIZE * 5, }; - memcpy(write_request.name, target_name, target_name_length); + memcpy(write_request.name, target_name.word, target_name_length); int32_t retcode; @@ -605,9 +606,9 @@ void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryIn struct CurrentDirectoryInfo target_directory = {}; copy_directory_info(&target_directory, info); int target_name_length = new_path_indexes[get_words_count(new_path_indexes) - 1].length; - char target_name[target_name_length]; + struct ParseString target_name; - invoke_cd(buf, 6, new_path_indexes, &target_directory, target_name); + invoke_cd(buf, 6, new_path_indexes, &target_directory, &target_name); // read the file from FATtable struct ClusterBuffer cl[5]; @@ -618,12 +619,12 @@ void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryIn }; struct ParseString target_filename = {}; - set_ParseString(&target_filename, target_name, target_name_length); + set_ParseString(&target_filename, target_name.word, target_name_length); struct ParseString target_file_name_parsed = {}; struct ParseString target_file_name_extension = {}; int split_result = split_filename_extension(&target_filename, &target_file_name_parsed, &target_file_name_extension); - memcpy(read_request.name, target_name, target_name_length); + memcpy(read_request.name, target_name.word, target_name_length); if (split_result != 0 && split_result != 1) { syscall(5, (uint32_t) "Invalid command!", 16, 0xF); @@ -646,56 +647,7 @@ void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryIn print_newline(); } } -/** - * Traverse all directories from ROOT to find a folder or file with name equals to target_name - * - * @param target_name file or folder name - * @param parent_cluster_number parent cluster number for the corresponding folder - * - * @return 0 : target_name not found; - * parent_cluster_number : target_name found at file or folder with parent_cluster_number; - */ -uint32_t traverse_directories(char *target_name, uint32_t parent_cluster_number) -{ - bool is_found = 0; - struct ClusterBuffer cl[10]; - struct FAT32DriverRequest read_folder_request = { - .buf = &cl, - .ext = EMPTY_EXTENSION, - .parent_cluster_number = parent_cluster_number, - .buffer_size = CLUSTER_SIZE * 10, - }; - - memcpy(read_folder_request.name, target_name, sizeof(target_name)); - - int32_t retcode; - syscall(1, (uint32_t)&read_folder_request, (uint32_t)&retcode, 0); - - if (retcode == 0) - { - struct FAT32DirectoryTable *dir_table = read_folder_request.buf; - - uint32_t counter_entry = 0; - for (uint32_t i = 0; i < 10 && !is_found && counter_entry < dir_table[0].table[0].n_of_entries; i++) - { - for (uint32_t j = 1; j < CLUSTER_SIZE / sizeof(struct FAT32DirectoryEntry) && !is_found && counter_entry < dir_table[0].table[0].n_of_entries; i++) - { - counter_entry++; - if (memcmp(dir_table[i].table[j].name, target_name, sizeof(target_name)) == 0) - { - is_found = parent_cluster_number; - } - else if (dir_table[i].table[j].attribute == ATTR_SUBDIRECTORY) - { - is_found = traverse_directories(target_name, (dir_table[i].table[j].cluster_high << 16) + - dir_table[i].table[j].cluster_low); - } - } - } - } - return is_found; -} /** * Calling syscall type-5 for printing the path after whereis command @@ -709,7 +661,7 @@ void print_path(uint32_t cluster_number) // root found - base condition if (cluster_number == ROOT_CLUSTER_NUMBER) { - syscall(5, (uint32_t) "/", 1, 0xF); + print_newline(); return; } @@ -731,7 +683,6 @@ void print_path(uint32_t cluster_number) print_path((dir_table->table->cluster_high << 16) + dir_table->table->cluster_low); syscall(5, (uint32_t) "/", 1, 0xF); syscall(5, (uint32_t)dir_table->table->name, 8, 0xF); - print_newline(); } } @@ -851,6 +802,63 @@ void mv_command(struct CurrentDirectoryInfo *source_dir, rm_command(source_dir, source_name); } +/** + * Handling command whereis in shell + * + * @param source_name target name to find + * + * @return 0 if no target found, 1 if target found + */ +uint32_t whereis_command(struct ParseString *source_name){ + // Create Search Request + struct RequestSearch search_request = {}; + + // Assign target name to search request + memcpy(search_request.search, source_name->word, 8); + + // Syscall to search target paths + syscall(7, (uint32_t)&search_request, 0, 0); + + // If no target found + if(search_request.result.n_of_items == 0){ + return 0; + } + + // Define colon and dot + char colon[1] = {':'}; + char dot[1] = {'.'}; + + // Print target name and colon + syscall(5, (uint32_t)source_name, 8, 0xF); + syscall(5, (uint32_t)colon, 1, 0xF); + + // Iterate all paths + uint32_t idx = 0; + while(idx < search_request.result.n_of_items){ + // Print path directory + print_path(search_request.result.parent_cluster_number[idx]); + + // Print target name + syscall(5, (uint32_t) "/", 1, 0xF); + syscall(5, (uint32_t)source_name, 8, 0xF); + + // If target is file, print dot + if(memcmp(search_request.result.ext[idx], "\0\0\0", 3) != 0){ + syscall(5, (uint32_t)dot, 1, 0xF); + } + + // Print extension + syscall(5, (uint32_t)search_request.result.ext[idx], 3, 0xF); + idx++; + } + + // Print newline to add space + print_newline(); + print_newline(); + + return 1; +} + int main(void) { const int DIRECTORY_DISPLAY_OFFSET = 24; @@ -1012,8 +1020,29 @@ int main(void) else if (commandNumber == 7) { + /* whereis Command */ + // Argument must be only 2 words + if (argsCount == 2) + { + // Setup search + struct ParseString find_name; + memcpy(find_name.word, buf + word_indexes[1].index, buf[word_indexes[1].length]); + find_name.length = 8; + + // Execute whereis command + uint32_t res = whereis_command(&find_name); + + // If no target found + if(!res){ + char msg[] = "Target not found!\n"; + syscall(5, (uint32_t)msg, 18, 0xF); + } + } else { + // If command is invalid + char msg[] = "Invalid command whereis!\n"; + syscall(5, (uint32_t)msg, 25, 0xF); + } } - else if (commandNumber == 8) { } From 5038577f947628bf60e489d0bd077b532c6bbb8e Mon Sep 17 00:00:00 2001 From: Fatih20 Date: Sat, 29 Apr 2023 18:27:02 +0700 Subject: [PATCH 080/101] Remove rmr and cpr command. --- src/user-shell.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index 4c85a10..1ca3c91 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -24,10 +24,11 @@ const char command_list[COMMAND_COUNT][COMMAND_MAX_SIZE] = { "rm\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "mv\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "whereis\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", - "rmr\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", - "cpr\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + }; struct CurrentDirectoryInfo From e969e93512192dd302a4b283cdc3323bbc7ae4ef Mon Sep 17 00:00:00 2001 From: sozyGithub Date: Sat, 29 Apr 2023 18:36:39 +0700 Subject: [PATCH 081/101] fix: invoke_cd --- src/user-shell.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index ffdeadb..a7109fa 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -346,11 +346,12 @@ uint8_t cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory while (j < dir_table->table->filesize / CLUSTER_SIZE && !found) { - for (int k = 1; k < CLUSTER_SIZE / (int) sizeof(struct FAT32DirectoryEntry) && !found; k++) + for (int k = 1; k < CLUSTER_SIZE / (int)sizeof(struct FAT32DirectoryEntry) && !found; k++) { struct FAT32DirectoryEntry *entry = &dir_table[j].table[k]; - if (entry->user_attribute != UATTR_NOT_EMPTY) continue; + if (entry->user_attribute != UATTR_NOT_EMPTY) + continue; char name[DIRECTORY_NAME_LENGTH] = "\0\0\0\0\0\0\0\0"; @@ -442,10 +443,11 @@ void ls_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf while (i < dir_table_count) { - for (int j = 1; j < CLUSTER_SIZE / (int) sizeof(struct FAT32DirectoryEntry); j++) + for (int j = 1; j < CLUSTER_SIZE / (int)sizeof(struct FAT32DirectoryEntry); j++) { - if (dirTable[i].table[j].user_attribute != UATTR_NOT_EMPTY) continue; - + if (dirTable[i].table[j].user_attribute != UATTR_NOT_EMPTY) + continue; + uint32_t color; if (dirTable[i].table[j].attribute == ATTR_SUBDIRECTORY) @@ -515,13 +517,18 @@ uint8_t invoke_cd(char *buf, parse_path_for_cd(buf, indexes, new_path_indexes); int last_word_index = get_words_count(new_path_indexes) - 1; - int new_buf_length = new_path_indexes[last_word_index - 1].index + new_path_indexes[last_word_index - 1].length; target_name->length = new_path_indexes[last_word_index].length; memcpy(target_name->word, buf + new_path_indexes[last_word_index].index, target_name->length); - if (get_words_count(new_path_indexes) > 1) + if (get_words_count(new_path_indexes) > 1 || buf[new_path_indexes[0].index - 1] == '/') { + int new_buf_length = new_path_indexes[last_word_index].index; + if (get_words_count(new_path_indexes) > 1) + { + new_buf_length = new_path_indexes[last_word_index - 1].index + new_path_indexes[last_word_index - 1].length; + } + char new_buf[new_buf_length]; for (int i = 0; i < new_buf_length; i++) { @@ -956,7 +963,6 @@ int8_t rm_command(struct CurrentDirectoryInfo *file_dir, struct ParseString *fil char msg[] = "File/folder not found.\n"; syscall(5, (uint32_t)msg, 24, 0xF); } - } return retcode; @@ -968,11 +974,12 @@ void mv_command(struct CurrentDirectoryInfo *source_dir, struct ParseString *dest_name) { uint8_t res = cp_command(source_dir, - source_name, - dest_dir, - dest_name); + source_name, + dest_dir, + dest_name); - if (res == 0) rm_command(source_dir, source_name); + if (res == 0) + rm_command(source_dir, source_name); } int main(void) @@ -1174,7 +1181,6 @@ int main(void) else if (argsCount == 3) { - } else From bdede203e487674be02d816efb97f16dc4280971 Mon Sep 17 00:00:00 2001 From: maikeljh Date: Sat, 29 Apr 2023 18:39:11 +0700 Subject: [PATCH 082/101] connect B+ Tree with Write --- src/fat32.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/fat32.c b/src/fat32.c index 360df70..d3acdf4 100644 --- a/src/fat32.c +++ b/src/fat32.c @@ -442,11 +442,13 @@ int8_t write(struct FAT32DriverRequest request) { if (memcmp("root\0\0\0\0", request.name, 8) == 0) return 3; create_subdirectory_from_entry(new_cluster_number, entry, request); + BPlusTree = insert(BPlusTree, request.name, request.ext, request.parent_cluster_number); return 0; } // Create a file create_file_from_entry(new_cluster_number, entry, request); + BPlusTree = insert(BPlusTree, request.name, request.ext, request.parent_cluster_number); return 0; } From ba0cd4022b458f3b2230e45126929a196d6af9e5 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Sat, 29 Apr 2023 18:50:02 +0700 Subject: [PATCH 083/101] feat: add recursive rm flag --- src/user-shell.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index ffdeadb..5280511 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -1147,11 +1147,10 @@ int main(void) else { - bool isFlagFound = FALSE; if (argsCount == 2) { - if (isFlagFound) + if (memcmp(buf+word_indexes[1].index, "-", 1) == 0) { syscall(5, (uint32_t)missing_args_msg, 21, 0xF); } @@ -1174,7 +1173,30 @@ int main(void) else if (argsCount == 3) { + if(word_indexes[1].length == 2 && memcmp(buf+word_indexes[1].index, "-r", 2) == 0) + { + // PAKAI WORD_INDEXES[2] SEBAGAI INDEKS AWAL PARAMETER PATH + char invalid_flag_msg[] = "Recursive rm.\n"; + syscall(5, (uint32_t)invalid_flag_msg, 15, 0xF); + } + + else if (word_indexes[2].length == 2 && memcmp(buf+word_indexes[2].index, "-r", 2) == 0) + { + // PAKAI WORD_INDEXES[1] SEBAGAI INDEKS AWAL PARAMETER PATH + char invalid_flag_msg[] = "Recursive rm.\n"; + syscall(5, (uint32_t)invalid_flag_msg, 15, 0xF); + } + else if (memcmp(buf+word_indexes[1].index, "-", 1) == 0 || memcmp(buf+word_indexes[2].index, "-", 1) == 0) + { + char invalid_flag_msg[] = "Invalid flag.\n"; + syscall(5, (uint32_t)invalid_flag_msg, 15, 0xF); + } + + else + { + syscall(5, (uint32_t)too_many_args_msg, 20, 0xF); + } } else From 264b9de7d90bd60c5a56dd8cf810e9dc08859878 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Sat, 29 Apr 2023 19:15:32 +0700 Subject: [PATCH 084/101] fix : incorrect type --- src/kernel.c | 4 ++++ src/user-shell.c | 10 +++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/kernel.c b/src/kernel.c index 9962004..064934a 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -71,6 +71,10 @@ void kernel_setup(void) req.parent_cluster_number = ROOT_CLUSTER_NUMBER; write(req); + memcpy(req.name, "a\0\0\0\0\0\0\0" , 8); + memcpy(req.ext, "\0\0\0", 3); + write(req); + // Write shell into memory struct FAT32DriverRequest request = { .buf = (uint8_t *)0, diff --git a/src/user-shell.c b/src/user-shell.c index 5280511..32f0de2 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -10,7 +10,7 @@ #define EXTENSION_NAME_LENGTH 3 #define INDEXES_MAX_COUNT SHELL_BUFFER_SIZE #define PATH_MAX_COUNT 64 -#define MAX_FILE_BUFFER_CLUSTER_SIZE 1 // take arbitrary size of 512 cluster = 512 * 4 * 512 B = 1MB +#define MAX_FILE_BUFFER_CLUSTER_SIZE 32 #define MAX_FOLDER_CLUSTER_SIZE 5 #define EMPTY_EXTENSION "\0\0\0" #define EMPTY_NAME "\0\0\0\0\0\0\0\0" @@ -336,7 +336,7 @@ uint8_t cd_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory request.parent_cluster_number = dir_table->table->cluster_low; } - int32_t retcode; + int8_t retcode; syscall(1, (uint32_t)&request, (uint32_t)&retcode, 0); @@ -429,7 +429,7 @@ void ls_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryInf memcpy(request.name, temp_info.paths[temp_info.current_path_count - 1], DIRECTORY_NAME_LENGTH); } - int32_t retcode; + int8_t retcode; syscall(1, (uint32_t)&request, (uint32_t)&retcode, 0); @@ -763,7 +763,7 @@ void print_path(uint32_t cluster_number) .buffer_size = CLUSTER_SIZE * 5, }; - int32_t retcode; + uint8_t retcode; syscall(6, (uint32_t)&read_folder_request, (uint32_t)&retcode, 0); if (retcode == 0) @@ -822,7 +822,7 @@ uint8_t cp_command(struct CurrentDirectoryInfo *source_dir, memcpy(read_request.ext, ext.word, ext.length); // copy file to buffer memory - int32_t retcode; + int8_t retcode; syscall(0, (uint32_t)&read_request, (uint32_t)&retcode, 0); if (retcode == 0) From af06d49f472f42c48feb44d0cdd36fb00c1552e2 Mon Sep 17 00:00:00 2001 From: maikeljh Date: Sat, 29 Apr 2023 19:19:19 +0700 Subject: [PATCH 085/101] connect B+tree with delete --- src/bplustree.c | 27 +++++++++++++++++++++++++++ src/fat32.c | 5 +++++ src/lib-header/bplustree.h | 19 +++++++++++++++---- 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/bplustree.c b/src/bplustree.c index e23ac8e..88c0d40 100644 --- a/src/bplustree.c +++ b/src/bplustree.c @@ -424,4 +424,31 @@ uint8_t whereis_main(struct RequestSearch *request){ request->result = *result; return 1; } +} + +void reset_nodes(){ + for(int i = 0; i < MAX_NODES; i++){ + // Reset Nodes + for(int j = 0 ; j < MAX_CHILDREN; j++){ + nodes[i].children[i] = NULL; + } + nodes[i].number_of_keys = 0; + nodes[i].leaf = FALSE; + nodes[i].parent = NULL; + + // Reset PCNodes + for(int j = 0; j < MAX_SAME_TARGET; j++){ + pcNodes[i].parent_cluster_number[i] = 0; + memcpy(pcNodes[i].ext, "\0\0\0", 3); + } + pcNodes[i].n_of_items = 0; + } +} + +void create_b_tree(){ + reset_nodes(); + + // Initialize B+ Tree + BPlusTree = make_tree("root\0\0\0\0", "\0\0\0", 2); + initialize_b_tree(BPlusTree, "root\0\0\0\0", 2, 2); } \ No newline at end of file diff --git a/src/fat32.c b/src/fat32.c index d3acdf4..00a8f12 100644 --- a/src/fat32.c +++ b/src/fat32.c @@ -520,11 +520,16 @@ int8_t delete(struct FAT32DriverRequest request) { // Folder is empty and can be deleted delete_subdirectory_by_entry(entry, request); + // Reset all nodes and initialize B+ Tree + create_b_tree(); return 0; } // Not a folder, delete as a file delete_file_by_entry(entry, request); + + // Reset all nodes and initialize B+ Tree + create_b_tree(); return 0; } diff --git a/src/lib-header/bplustree.h b/src/lib-header/bplustree.h index e447c18..effc536 100644 --- a/src/lib-header/bplustree.h +++ b/src/lib-header/bplustree.h @@ -4,8 +4,9 @@ #include "stdtype.h" #include "fat32.h" -#define MAX_NODES 256 -#define MAX_CHILDREN 5 +#define MAX_NODES 512 +#define MAX_CHILDREN 7 +#define MAX_SAME_TARGET 50 #define NULL ((void *)0) /* -- B+ Tree -- */ @@ -17,8 +18,8 @@ */ struct PCNode { - uint32_t parent_cluster_number[MAX_CHILDREN]; - char ext[MAX_CHILDREN][3]; + uint32_t parent_cluster_number[MAX_SAME_TARGET]; + char ext[MAX_SAME_TARGET][3]; uint32_t n_of_items; }; @@ -187,4 +188,14 @@ void initialize_b_tree(struct NodeFileSystem *root, char* dir_name, uint32_t par */ uint8_t whereis_main(struct RequestSearch *request); +/** + * @brief Reset all nodes + */ +void reset_nodes(); + +/** + * @brief Initialize B+ Tree with Root + */ +void create_b_tree(); + #endif From 5b22062e89bcb605499fe710f2c1cca96264d7e6 Mon Sep 17 00:00:00 2001 From: maikeljh <87570374+maikeljh@users.noreply.github.com> Date: Sat, 29 Apr 2023 19:31:42 +0700 Subject: [PATCH 086/101] Update user-shell.c --- src/user-shell.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index d74ec27..6026d12 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -1222,7 +1222,7 @@ int main(void) } else if (commandNumber == 6) - { + { // mv_command if (argsCount == 1) { @@ -1250,8 +1250,16 @@ int main(void) // get destination directory info & source file name invoke_cd(buf, word_indexes + 2, &dest_dir, &dest_name); - } + + // invoke mv command + mv_command(&source_dir, &source_name, &dest_dir, &dest_name); + } + else + { + syscall(5, (uint32_t)too_many_args_msg, 20, 0xF); + } } + else if (commandNumber == 7) { /* whereis Command */ @@ -1277,6 +1285,7 @@ int main(void) syscall(5, (uint32_t)msg, 25, 0xF); } } + else if (commandNumber == 8) { } From 2c636bb4a3878e3455be4505f2f99df53a8d8b4b Mon Sep 17 00:00:00 2001 From: maikeljh <87570374+maikeljh@users.noreply.github.com> Date: Sat, 29 Apr 2023 19:33:26 +0700 Subject: [PATCH 087/101] Update user-shell.c --- src/user-shell.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index 6026d12..1a7c6e8 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -579,6 +579,7 @@ void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory uint8_t cd_res = invoke_cd(buf, indexes, &target_directory, &target_name); if (cd_res == 0) + return; // create new directory in the target_directory struct FAT32DriverRequest write_request = { @@ -588,7 +589,6 @@ void mkdir_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectory .buffer_size = 0, }; - memcpy(write_request.name, target_name.word, target_name.length); int8_t retcode; @@ -647,7 +647,6 @@ void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryIn struct ParseString target_filename = {}; set_ParseString(&target_filename, target_name.word, target_name.length); - struct ParseString target_file_name_parsed = {}; struct ParseString target_file_name_extension = {}; int split_result = split_filename_extension(&target_filename, &target_file_name_parsed, &target_file_name_extension); From bc09f886cde219fac774ff023e839da8394d33f8 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Sat, 29 Apr 2023 20:07:35 +0700 Subject: [PATCH 088/101] feat: add filesize adjustment to cp --- src/kernel.c | 7 ++-- src/user-shell.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 91 insertions(+), 5 deletions(-) diff --git a/src/kernel.c b/src/kernel.c index 064934a..148f559 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -41,8 +41,9 @@ void kernel_setup(void) memcpy(req.name, "f3", 2); write(req); + uint32_t f1 = 0xb; // move parent to f1 - req.parent_cluster_number = 0xb; + req.parent_cluster_number = f1; memcpy(req.name, "f4", 2); write(req); @@ -51,12 +52,12 @@ void kernel_setup(void) write(req); // move parent to f1 - req.parent_cluster_number = 0xe; + req.parent_cluster_number = f1+3; memcpy(req.name, "f6", 2); write(req); - req.parent_cluster_number = 0x10; + req.parent_cluster_number = f1+4; memcpy(req.name, "f7", 2); write(req); diff --git a/src/user-shell.c b/src/user-shell.c index 9163356..5eeda0e 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -784,6 +784,68 @@ void print_path(uint32_t cluster_number) } } +uint32_t get_file_size(uint32_t current_cluster_number, char* current_folder_name, char* file_name, char* ext) +{ + // return 0 if not found + + struct ClusterBuffer cl[MAX_FOLDER_CLUSTER_SIZE]; + + struct FAT32DriverRequest request = { + .buf = &cl, + .name = "root\0\0\0\0", + .ext = "\0\0\0", + .parent_cluster_number = current_cluster_number, + .buffer_size = CLUSTER_SIZE * MAX_FOLDER_CLUSTER_SIZE, + }; + + struct FAT32DirectoryTable *dir_table; + + if (current_cluster_number > ROOT_CLUSTER_NUMBER) + { + syscall(6, (uint32_t)&request, 0, 0); + + dir_table = request.buf; + + memcpy(request.name, current_folder_name, DIRECTORY_NAME_LENGTH); + + request.parent_cluster_number = dir_table->table->cluster_low; + } + + int8_t retcode; + + syscall(1, (uint32_t)&request, (uint32_t)&retcode, 0); + + dir_table = request.buf; + uint32_t j = 0; + struct FAT32DirectoryEntry *entry; + bool found = FALSE; + + while (j < dir_table->table->filesize / CLUSTER_SIZE && !found) + { + for (int k = 1; k < CLUSTER_SIZE / (int)sizeof(struct FAT32DirectoryEntry) && !found; k++) + { + entry = &dir_table[j].table[k]; + + if (entry->user_attribute != UATTR_NOT_EMPTY) + continue; + + if (memcmp(entry->name, file_name, DIRECTORY_NAME_LENGTH) == 0 && memcmp(entry->ext, ext, EXTENSION_NAME_LENGTH) == 0) + + { + found = TRUE; + } + } + + j++; + } + + if (!found) + { + return 0; + } + + return entry->filesize; +} /** * cp command in shell, copy the file in specified source directory to the specified destination directory with new name * @param source_dir directory of file to be copied @@ -802,6 +864,8 @@ uint8_t cp_command(struct CurrentDirectoryInfo *source_dir, // prepare buffer in memory for copying struct ClusterBuffer cl[MAX_FILE_BUFFER_CLUSTER_SIZE]; + reset_buffer((char*)cl, CLUSTER_SIZE * MAX_FILE_BUFFER_CLUSTER_SIZE); + /* READING STAGE */ struct ParseString name; @@ -837,6 +901,19 @@ uint8_t cp_command(struct CurrentDirectoryInfo *source_dir, // read file to buffer success /* WRITING STAGE */ + char file_name[] = EMPTY_NAME; + char file_ext[] = EMPTY_EXTENSION; + memcpy(file_name, name.word, name.length); + memcpy(file_ext, ext.word, ext.length); + + char source_dir_name[] = "root\0\0\0\0"; + + if (source_dir->current_cluster_number > ROOT_CLUSTER_NUMBER) + { + memcpy(source_dir_name, source_dir->paths[source_dir->current_path_count-1], DIRECTORY_NAME_LENGTH); + } + uint32_t file_size = get_file_size(source_dir->current_cluster_number, source_dir_name, file_name, file_ext); + // split source filename to name and extension splitcode = split_filename_extension(dest_name, &name, &ext); if (splitcode == 2 || splitcode == 3) @@ -846,13 +923,21 @@ uint8_t cp_command(struct CurrentDirectoryInfo *source_dir, // return; } + if (file_size == 0) + { + char errorMsg[] = "Error: file/folder not found.\n"; + syscall(5, (uint32_t)errorMsg, 31, 0xF); + + return 1; + } + // prepare write file request struct FAT32DriverRequest write_request = { .buf = cl, - // .name = EMPTY_NAME, + .name = EMPTY_NAME, .ext = EMPTY_EXTENSION, .parent_cluster_number = dest_dir->current_cluster_number, - .buffer_size = CLUSTER_SIZE * MAX_FILE_BUFFER_CLUSTER_SIZE, + .buffer_size = file_size, }; memcpy(write_request.name, name.word, name.length); memcpy(write_request.ext, ext.word, ext.length); From 7178aa3c14f6510aab79e3450d6250b537746302 Mon Sep 17 00:00:00 2001 From: maikeljh Date: Sat, 29 Apr 2023 20:09:33 +0700 Subject: [PATCH 089/101] fix b+tree bug --- src/bplustree.c | 4 +++- src/kernel.c | 10 +++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/bplustree.c b/src/bplustree.c index 88c0d40..cfc00ef 100644 --- a/src/bplustree.c +++ b/src/bplustree.c @@ -394,6 +394,7 @@ void initialize_b_tree(struct NodeFileSystem *root, char *dir_name, uint32_t par for (uint32_t j = 1; j < CLUSTER_SIZE / sizeof(struct FAT32DirectoryEntry) && counter_entry < dir_table[0].table[0].n_of_entries; j++) { counter_entry++; + root = BPlusTree; if (dir_table[i].table[j].attribute == ATTR_SUBDIRECTORY) { BPlusTree = insert(root, dir_table[i].table[j].name, dir_table[i].table[j].ext, dir_cluster_number); @@ -406,7 +407,8 @@ void initialize_b_tree(struct NodeFileSystem *root, char *dir_name, uint32_t par } else if (!is_entry_empty(&dir_table[i].table[j])) { - insert(root, dir_table[i].table[j].name, dir_table[i].table[j].ext, dir_cluster_number); + BPlusTree = insert(root, dir_table[i].table[j].name, dir_table[i].table[j].ext, dir_cluster_number); + root = BPlusTree; } } } diff --git a/src/kernel.c b/src/kernel.c index 70553a8..7c3c69a 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -35,7 +35,7 @@ void kernel_setup(void) }; write(req); - req.parent_cluster_number = 0xA; + req.parent_cluster_number = 0xB; memcpy(req.name, "f2", 2); write(req); @@ -46,14 +46,14 @@ void kernel_setup(void) write(req); // move parent to f2 - req.parent_cluster_number = 0xB; + req.parent_cluster_number = 0xC; req.buffer_size = 0; memcpy(req.ext, "\0\0\0", 3); memcpy(req.name, "f4", 2); write(req); - req.parent_cluster_number = 0xD; + req.parent_cluster_number = 0xE; req.buffer_size = 10; memcpy(req.name, "f5", 2); memcpy(req.ext, "jir", 3); @@ -70,12 +70,12 @@ void kernel_setup(void) memcpy(req.ext, "tot", 3); write(req); - req.parent_cluster_number = 0xe; + req.parent_cluster_number = 0xE; memcpy(req.name, "f6", 2); write(req); - req.parent_cluster_number = 0x10; + req.parent_cluster_number = 0xB; memcpy(req.name, "f7", 2); write(req); From 8d7bc9fa5a5bd29793a06894a20d1ae4e35eaef9 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Sat, 29 Apr 2023 20:38:52 +0700 Subject: [PATCH 090/101] refactor: reset buffer --- src/fat32.c | 2 -- src/kernel.c | 31 ++++++------------------------- src/user-shell.c | 2 ++ 3 files changed, 8 insertions(+), 27 deletions(-) diff --git a/src/fat32.c b/src/fat32.c index 00a8f12..b7fbc3f 100644 --- a/src/fat32.c +++ b/src/fat32.c @@ -129,8 +129,6 @@ void initialize_filesystem_fat32(void) { BPlusTree = make_tree("root\0\0\0\0", "\0\0\0", 2); initialize_b_tree(BPlusTree, "root\0\0\0\0", 2, 2); - struct NodeFileSystem *tes = BPlusTree; - if(tes->leaf){} // Initialize static array for empty clusters for (int i = 0; i < CLUSTER_SIZE; i++) { empty_cluster_value[i] = 0; diff --git a/src/kernel.c b/src/kernel.c index e3a05c5..4a71674 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -35,49 +35,26 @@ void kernel_setup(void) }; write(req); - req.parent_cluster_number = 0xB; memcpy(req.name, "f2", 2); write(req); - req.parent_cluster_number = ROOT_CLUSTER_NUMBER; - req.buffer_size = 10; memcpy(req.name, "f3", 2); - memcpy(req.ext, "jav", 3); write(req); uint32_t f1 = 0xb; // move parent to f1 req.parent_cluster_number = f1; - memcpy(req.name, "f4", 2); - write(req); - - // move parent to f2 - req.parent_cluster_number = f1+1; - req.buffer_size = 0; - memcpy(req.ext, "\0\0\0", 3); memcpy(req.name, "f4", 2); write(req); - req.parent_cluster_number = 0xE; - req.buffer_size = 10; memcpy(req.name, "f5", 2); - memcpy(req.ext, "jir", 3); write(req); // move parent to f1 req.parent_cluster_number = f1+3; - memcpy(req.name, "f6", 2); - write(req); - // move parent to f2 - req.parent_cluster_number = f1+1; - memcpy(req.name, "f4", 2); - memcpy(req.ext, "gob", 3); - write(req); - - memcpy(req.name, "f5", 2); - memcpy(req.ext, "tot", 3); + memcpy(req.name, "f6", 2); write(req); req.parent_cluster_number = f1+4; @@ -88,8 +65,12 @@ void kernel_setup(void) memcpy(req.name, "file1", 5); memcpy(req.ext, "txt", 3); struct ClusterBuffer cl = { - .buf = "freestar freestar Lorem ipsum dolor sit amet, consectetur adipiscing elit.Ut efficitur dui magna, nec tincidunt risus malesuada sit amet.Nam ligula mi, lacinia sed ornare sit amet, imperdiet ac sem.Nunc ac sapien dignissim, mollis augue sed, gravida dolor.Aenean blandit libero et massa gravida, eu tristique urna congue.Aenean quis tempor nisl, efficitur efficitur ligula.Sed consectetur iaculis risus et tempor.Aenean fringilla consectetur urna, ut dapibus est rhoncus nec.Cras accumsan ut justo vel hendrerit.Duis imperdiet quam ac malesuada hendrerit.Morbi eget tortor faucibus,elementum elit sit amet, blandit nunc.Maecenas rutrum facilisis lorem, in ultricies nisl molestie et.Proin sit amet ipsum at mi luctus pellentesque dapibus quis mi.Integer aliquet velit sit amet odio aliquet posuere.Ut ultrices ac magna fermentum malesuada.Proin nec rhoncus enim.Etiam id metus id nibh convallis venenatis.Nunc quis purus vulputate sem volutpat porttitor et non metus.Vestibulum commodo luctus neque ut congue.Etiam consectetur urna ut lectus maximus rhoncus.Vivamus a leo ut nisl feugiat pulvinar eget et diam.Nullam vitae ultrices arcu.Proin non sapien quis velit vulputate congue.Nulla pellentesque feugiat tempor.", + }; + + for (uint32_t i = 0; i < CLUSTER_SIZE; i++) cl.buf[i] = '\0'; + + memcpy(&cl, "freestar freestar Lorem ipsum dolor sit amet, consectetur adipiscing elit.Ut efficitur dui magna, nec tincidunt risus malesuada sit amet.Nam ligula mi, lacinia sed ornare sit amet, imperdiet ac sem.Nunc ac sapien dignissim, mollis augue sed, gravida dolor.Aenean blandit libero et massa gravida, eu tristique urna congue.Aenean quis tempor nisl, efficitur efficitur ligula.Sed consectetur iaculis risus et tempor.Aenean fringilla consectetur urna, ut dapibus est rhoncus nec.Cras accumsan ut justo vel hendrerit.Duis imperdiet quam ac malesuada hendrerit.Morbi eget tortor faucibus,elementum elit sit amet, blandit nunc.Maecenas rutrum facilisis lorem, in ultricies nisl molestie et.Proin sit amet ipsum at mi luctus pellentesque dapibus quis mi.Integer aliquet velit sit amet odio aliquet posuere.Ut ultrices ac magna fermentum malesuada.Proin nec rhoncus enim.Etiam id metus id nibh convallis venenatis.Nunc quis purus vulputate sem volutpat porttitor et non metus.Vestibulum commodo luctus neque ut congue.Etiam consectetur urna ut lectus maximus rhoncus.Vivamus a leo ut nisl feugiat pulvinar eget et diam.Nullam vitae ultrices arcu.Proin non sapien quis velit vulputate congue.Nulla pellentesque feugiat tempor.", 1224); req.buf = &cl; req.buffer_size = CLUSTER_SIZE; req.parent_cluster_number = ROOT_CLUSTER_NUMBER; diff --git a/src/user-shell.c b/src/user-shell.c index f063543..50a5ae8 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -639,6 +639,8 @@ void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryIn // read the file from FATtable struct ClusterBuffer cl[MAX_FILE_BUFFER_CLUSTER_SIZE]; + reset_buffer((char*) cl, CLUSTER_SIZE * MAX_FILE_BUFFER_CLUSTER_SIZE); + struct FAT32DriverRequest read_request = { .buf = &cl, .parent_cluster_number = target_directory.current_cluster_number, From b1ab6cd266130858188304d25fff09a7aa75ea81 Mon Sep 17 00:00:00 2001 From: Fatih20 Date: Sat, 29 Apr 2023 20:40:35 +0700 Subject: [PATCH 091/101] Fix subtle bug in recursive deletion. --- src/fat32.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/fat32.c b/src/fat32.c index abba46c..ac855dc 100644 --- a/src/fat32.c +++ b/src/fat32.c @@ -501,6 +501,7 @@ int8_t delete(struct FAT32DriverRequest request, bool is_recursive, bool check_r uint16_t now_cluster_number = request.parent_cluster_number; uint16_t prev_cluster_number; + uint16_t nth_entry; while (!end_of_directory && !found_directory) { @@ -512,6 +513,10 @@ int8_t delete(struct FAT32DriverRequest request, bool is_recursive, bool check_r if (!is_entry_empty(entry)) { found_directory = is_dir_ext_name_same(entry, request); + if (found_directory) + { + nth_entry = i; + } } else @@ -531,7 +536,9 @@ int8_t delete(struct FAT32DriverRequest request, bool is_recursive, bool check_r // If file is found, get out of the loop if (found_directory) + { continue; + } // Move onto the next cluster if it's not the end yet if (!end_of_directory) @@ -574,7 +581,7 @@ int8_t delete(struct FAT32DriverRequest request, bool is_recursive, bool check_r uint16_t entry_cluster_position = entry->cluster_low; // If check recursion is false, no checking will be done - if (check_recursion && !is_below_max_recursion_depth(entry->cluster_low, 0)) + if (check_recursion && !is_below_max_recursion_depth(entry_cluster_position, 0)) { return 5; } @@ -586,7 +593,7 @@ int8_t delete(struct FAT32DriverRequest request, bool is_recursive, bool check_r read_clusters(&driver_state.dir_table_buf, request.parent_cluster_number, 1); // Delete the directory itself - delete_subdirectory_by_entry(entry, request); + delete_subdirectory_by_entry(&driver_state.dir_table_buf.table[nth_entry], request); return 0; } @@ -679,6 +686,9 @@ void delete_subdirectory_content(uint16_t target_cluster_number) { memcpy(&(req.name), &(entry->name), 8); delete (req, TRUE, FALSE); + + // Reset the content of the driver state to before deletion + read_clusters(&driver_state.dir_table_buf, target_cluster_number, 1); } else { @@ -1095,13 +1105,14 @@ bool is_below_max_recursion_depth(uint16_t target_cluster_number, uint8_t recurs i++) { entry = &(driver_state.dir_table_buf.table[i]); - if (is_subdirectory(entry)) + if (!is_entry_empty(entry) && is_subdirectory(entry)) { // Return false if recursive checking finds the subdirectory in the directory too deep if (!is_below_max_recursion_depth(entry->cluster_low, recursion_count + 1)) { return FALSE; } + read_clusters(&driver_state.dir_table_buf, target_cluster_number, 1); } } From 64789af9ca656b9fd76ce22f5e30fd053b230297 Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Sat, 29 Apr 2023 21:04:33 +0700 Subject: [PATCH 092/101] feat: add delete restriction --- src/user-shell.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/user-shell.c b/src/user-shell.c index 50a5ae8..c31f8f9 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -968,6 +968,13 @@ int8_t rm_command(struct CurrentDirectoryInfo *file_dir, struct ParseString *fil return 1; } + if (name.length == 5 && memcmp(name.word, "shell", 5) == 0 && ext.length == 0) + { + char msg[] = "Shell program can not be deleted.\n"; + syscall(5, (uint32_t)msg, 35, 0xF); + return -1; + } + // create delete request struct FAT32DriverRequest delete_request = { .name = EMPTY_NAME, From c7004473fae93aee1e4732730326d7204230491e Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Sat, 29 Apr 2023 21:06:11 +0700 Subject: [PATCH 093/101] refactor: change testing address --- src/kernel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kernel.c b/src/kernel.c index 4a71674..f49e9ee 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -41,7 +41,7 @@ void kernel_setup(void) memcpy(req.name, "f3", 2); write(req); - uint32_t f1 = 0xb; + uint32_t f1 = 0xc; // move parent to f1 req.parent_cluster_number = f1; From 32aac55d91d6c2e2d1c8aef43d9c896ef181bebd Mon Sep 17 00:00:00 2001 From: Fatih20 Date: Sat, 29 Apr 2023 21:06:52 +0700 Subject: [PATCH 094/101] Tidying up delete. --- src/user-shell.c | 50 ++++++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index 614ca6e..1860342 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -954,7 +954,7 @@ uint8_t cp_command(struct CurrentDirectoryInfo *source_dir, * @param is_recursive whether the rm command should be recursive * @return - */ -int8_t rm_command(struct CurrentDirectoryInfo *file_dir, struct ParseString *file_name, bool is_recursive) +void rm_command(struct CurrentDirectoryInfo *file_dir, struct ParseString *file_name, bool is_recursive) { struct ParseString name; struct ParseString ext; @@ -966,14 +966,14 @@ int8_t rm_command(struct CurrentDirectoryInfo *file_dir, struct ParseString *fil { char msg[] = "Source file not found.\n"; syscall(5, (uint32_t)msg, 24, 0xF); - return 1; + return; } if (name.length == 5 && memcmp(name.word, "shell", 5) == 0 && ext.length == 0) { char msg[] = "Shell program can not be deleted.\n"; syscall(5, (uint32_t)msg, 35, 0xF); - return -1; + return; } // create delete request @@ -989,28 +989,32 @@ int8_t rm_command(struct CurrentDirectoryInfo *file_dir, struct ParseString *fil int8_t retcode; syscall(3, (uint32_t)&delete_request, (uint32_t)&retcode, is_recursive); - if (retcode != 0) + switch (retcode) { - if (retcode == 2) - { - char msg[] = "Folder is not empty.\n"; - syscall(5, (uint32_t)msg, 22, 0xF); - } - - else if (retcode == -1) - { - char msg[] = "Unknown error.\n"; - syscall(5, (uint32_t)msg, 16, 0xF); - } - - else - { - char msg[] = "File/folder not found.\n"; - syscall(5, (uint32_t)msg, 24, 0xF); - } + case 1: + char msg[] = "File/folder not found.\n"; + syscall(5, (uint32_t)msg, 22, 0xF); + break; + case 2: + char msg[] = "Folder is not empty.\n"; + syscall(5, (uint32_t)msg, 22, 0xF); + break; + case 4: + char msg[] = "Invalid parent.\n"; + syscall(5, (uint32_t)msg, 24, 0xF); + break; + case 5: + char msg[] = "Exceeding maximum recursion depth.\n"; + syscall(5, (uint32_t)msg, 24, 0xF); + break; + case -1: + char msg[] = "Unknown error.\n"; + syscall(5, (uint32_t)msg, 16, 0xF); + break; + default: + break; } - - return retcode; + return; } void mv_command(struct CurrentDirectoryInfo *source_dir, From 440715cc7e473a194ddb4e654dd8e4cc07efe34e Mon Sep 17 00:00:00 2001 From: Fatih20 Date: Sat, 29 Apr 2023 21:23:40 +0700 Subject: [PATCH 095/101] Fix switch error. --- src/user-shell.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/user-shell.c b/src/user-shell.c index 1860342..cf9532a 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -992,25 +992,35 @@ void rm_command(struct CurrentDirectoryInfo *file_dir, struct ParseString *file_ switch (retcode) { case 1: + { char msg[] = "File/folder not found.\n"; syscall(5, (uint32_t)msg, 22, 0xF); break; + } case 2: + { char msg[] = "Folder is not empty.\n"; syscall(5, (uint32_t)msg, 22, 0xF); break; + } case 4: + { char msg[] = "Invalid parent.\n"; syscall(5, (uint32_t)msg, 24, 0xF); break; + } case 5: + { char msg[] = "Exceeding maximum recursion depth.\n"; syscall(5, (uint32_t)msg, 24, 0xF); break; + } case -1: + { char msg[] = "Unknown error.\n"; syscall(5, (uint32_t)msg, 16, 0xF); break; + } default: break; } From e3f8c354ddd4ca28d787ac7ab59f9512519a777a Mon Sep 17 00:00:00 2001 From: sozyGithub Date: Sat, 29 Apr 2023 22:11:46 +0700 Subject: [PATCH 096/101] fix: invoke_cd --- src/user-shell.c | 160 ++++++++++++++++++++++++----------------------- 1 file changed, 82 insertions(+), 78 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index cf9532a..b36eacd 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -525,27 +525,77 @@ uint8_t invoke_cd(char *buf, if (get_words_count(new_path_indexes) > 1 || buf[new_path_indexes[0].index - 1] == '/') { - int new_buf_length = new_path_indexes[last_word_index].index; - if (get_words_count(new_path_indexes) > 1) - { - new_buf_length = new_path_indexes[last_word_index - 1].index + new_path_indexes[last_word_index - 1].length; - } + struct IndexInfo new_indexes[INDEXES_MAX_COUNT]; + memcpy(new_indexes, indexes, INDEXES_MAX_COUNT); + new_indexes[0].length -= target_name->length; + // call cd command to move the directory + return cd_command(buf, new_indexes, target_directory); + } + + return 1; +} + +uint32_t get_file_size(uint32_t current_cluster_number, char *current_folder_name, char *file_name, char *ext) +{ + // return 0 if not found - char new_buf[new_buf_length]; - for (int i = 0; i < new_buf_length; i++) + struct ClusterBuffer cl[MAX_FOLDER_CLUSTER_SIZE]; + + struct FAT32DriverRequest request = { + .buf = &cl, + .name = "root\0\0\0\0", + .ext = "\0\0\0", + .parent_cluster_number = current_cluster_number, + .buffer_size = CLUSTER_SIZE * MAX_FOLDER_CLUSTER_SIZE, + }; + + struct FAT32DirectoryTable *dir_table; + + if (current_cluster_number > ROOT_CLUSTER_NUMBER) + { + syscall(6, (uint32_t)&request, 0, 0); + + dir_table = request.buf; + + memcpy(request.name, current_folder_name, DIRECTORY_NAME_LENGTH); + + request.parent_cluster_number = dir_table->table->cluster_low; + } + + int8_t retcode; + + syscall(1, (uint32_t)&request, (uint32_t)&retcode, 0); + + dir_table = request.buf; + uint32_t j = 0; + struct FAT32DirectoryEntry *entry; + bool found = FALSE; + + while (j < dir_table->table->filesize / CLUSTER_SIZE && !found) + { + for (int k = 1; k < CLUSTER_SIZE / (int)sizeof(struct FAT32DirectoryEntry) && !found; k++) { - new_buf[i] = buf[i]; + entry = &dir_table[j].table[k]; + + if (entry->user_attribute != UATTR_NOT_EMPTY) + continue; + + if (memcmp(entry->name, file_name, DIRECTORY_NAME_LENGTH) == 0 && memcmp(entry->ext, ext, EXTENSION_NAME_LENGTH) == 0) + + { + found = TRUE; + } } - struct IndexInfo new_buf_indexes[INDEXES_MAX_COUNT]; - reset_indexes(new_buf_indexes, INDEXES_MAX_COUNT); - // [path_segment_1] [path_segment_2] [path_segment_3] ... - get_buffer_indexes(new_buf, new_buf_indexes, ' ', 0, new_buf_length); - // call cd command to move the directory - return cd_command(new_buf, new_buf_indexes + 1, target_directory); + j++; } - return 1; + if (!found) + { + return 0; + } + + return entry->filesize; } /** @@ -660,6 +710,22 @@ void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryIn print_newline(); return; } + struct IndexInfo new_path_indexes[INDEXES_MAX_COUNT]; + parse_path_for_cd(buf, indexes, new_path_indexes); + + struct ClusterBuffer cl_read_folder[5]; + struct FAT32DriverRequest read_folder_request = { + .buf = &cl_read_folder, + .ext = EMPTY_EXTENSION, + .parent_cluster_number = target_directory.current_cluster_number, + .buffer_size = CLUSTER_SIZE * 5, + }; + + int8_t retcode_read_folder; + syscall(6, (uint32_t)&read_folder_request, (uint32_t)&retcode_read_folder, 0); + struct FAT32DirectoryTable *dir_table = read_folder_request.buf; + + uint32_t file_size = get_file_size(target_directory.current_cluster_number, dir_table->table->name, target_file_name_parsed.word, target_file_name_extension.word); memcpy(read_request.name, target_file_name_parsed.word, target_file_name_parsed.length); memcpy(read_request.ext, target_file_name_extension.word, target_file_name_extension.length); @@ -670,7 +736,7 @@ void cat_command(char *buf, struct IndexInfo *indexes, struct CurrentDirectoryIn if (retcode == 0) { - syscall(5, (uint32_t)read_request.buf, read_request.buffer_size, 0xF); + syscall(5, (uint32_t)read_request.buf, file_size, 0xF); print_newline(); } else if (retcode == 1) @@ -737,68 +803,6 @@ void print_path(uint32_t cluster_number) } } -uint32_t get_file_size(uint32_t current_cluster_number, char *current_folder_name, char *file_name, char *ext) -{ - // return 0 if not found - - struct ClusterBuffer cl[MAX_FOLDER_CLUSTER_SIZE]; - - struct FAT32DriverRequest request = { - .buf = &cl, - .name = "root\0\0\0\0", - .ext = "\0\0\0", - .parent_cluster_number = current_cluster_number, - .buffer_size = CLUSTER_SIZE * MAX_FOLDER_CLUSTER_SIZE, - }; - - struct FAT32DirectoryTable *dir_table; - - if (current_cluster_number > ROOT_CLUSTER_NUMBER) - { - syscall(6, (uint32_t)&request, 0, 0); - - dir_table = request.buf; - - memcpy(request.name, current_folder_name, DIRECTORY_NAME_LENGTH); - - request.parent_cluster_number = dir_table->table->cluster_low; - } - - int8_t retcode; - - syscall(1, (uint32_t)&request, (uint32_t)&retcode, 0); - - dir_table = request.buf; - uint32_t j = 0; - struct FAT32DirectoryEntry *entry; - bool found = FALSE; - - while (j < dir_table->table->filesize / CLUSTER_SIZE && !found) - { - for (int k = 1; k < CLUSTER_SIZE / (int)sizeof(struct FAT32DirectoryEntry) && !found; k++) - { - entry = &dir_table[j].table[k]; - - if (entry->user_attribute != UATTR_NOT_EMPTY) - continue; - - if (memcmp(entry->name, file_name, DIRECTORY_NAME_LENGTH) == 0 && memcmp(entry->ext, ext, EXTENSION_NAME_LENGTH) == 0) - - { - found = TRUE; - } - } - - j++; - } - - if (!found) - { - return 0; - } - - return entry->filesize; -} /** * cp command in shell, copy the file in specified source directory to the specified destination directory with new name * @param source_dir directory of file to be copied From 8fdd796ed539cab458e0ecf11ea403602f11852b Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Sat, 29 Apr 2023 22:45:20 +0700 Subject: [PATCH 097/101] feat: add remove safety checking --- src/user-shell.c | 79 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 72 insertions(+), 7 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index cf9532a..25eb5d6 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -947,6 +947,45 @@ uint8_t cp_command(struct CurrentDirectoryInfo *source_dir, return 0; } +bool is_rm_safe(struct CurrentDirectoryInfo *target_dir, struct ParseString folder_name, struct CurrentDirectoryInfo *current_dir) +{ + char name[] = EMPTY_NAME; + memcpy(name, folder_name.word, folder_name.length); + + uint16_t current_cluster_number = current_dir->current_cluster_number; + uint32_t path_count = current_dir->current_path_count; + + if (current_cluster_number == ROOT_CLUSTER_NUMBER) return TRUE; + + bool found = FALSE; + do + { + struct ClusterBuffer cl = {0}; + struct FAT32DriverRequest request = { + .buf = &cl, + .name = "\0\0\0\0\0\0\0\0", + .ext = "\0\0\0", + .parent_cluster_number = current_cluster_number, + .buffer_size = CLUSTER_SIZE, + }; + syscall(6, (uint32_t)&request, 0, 0); + struct FAT32DirectoryTable *dir_table = request.buf; + current_cluster_number = dir_table->table->cluster_low; + path_count--; + found = (current_cluster_number == target_dir->current_cluster_number) + && (memcmp(current_dir->paths[path_count-1], name, DIRECTORY_NAME_LENGTH) == 0); + } + + while(current_cluster_number != ROOT_CLUSTER_NUMBER && !found); + + if (found) + { + return FALSE; + } + + return TRUE; +} + /** * rm command in shell, removes the specified file in the specified directory * @param file_dir directory of file to be removed @@ -1293,8 +1332,17 @@ int main(void) // get source directory info & source file name invoke_cd(buf, word_indexes + 1, &target_dir, &target_name); - // invoke rm command - rm_command(&target_dir, &target_name, FALSE); + if (is_rm_safe(&target_dir, target_name, ¤t_directory_info)) + { + // invoke rm command + rm_command(&target_dir, &target_name, FALSE); + } + + else + { + char not_safe_msg = "Current directory is inside the folder."; + syscall(5, (uint32_t)not_safe_msg, 40, 0xF); + } } } @@ -1312,9 +1360,17 @@ int main(void) // get source directory info & source file name invoke_cd(buf, word_indexes + 2, &target_dir, &target_name); - // invoke rm command - rm_command(&target_dir, &target_name, TRUE); - + if (is_rm_safe(&target_dir, target_name, ¤t_directory_info)) + { + // invoke rm command + rm_command(&target_dir, &target_name, TRUE); + } + + else + { + char not_safe_msg = "Current directory is inside the folder."; + syscall(5, (uint32_t)not_safe_msg, 40, 0xF); + } // char invalid_flag_msg[] = "Recursive rm.\n"; // syscall(5, (uint32_t)invalid_flag_msg, 15, 0xF); } @@ -1331,8 +1387,17 @@ int main(void) // get source directory info & source file name invoke_cd(buf, word_indexes + 1, &target_dir, &target_name); - // invoke rm command - rm_command(&target_dir, &target_name, TRUE); + if (is_rm_safe(&target_dir, target_name, ¤t_directory_info)) + { + // invoke rm command + rm_command(&target_dir, &target_name, TRUE); + } + + else + { + char not_safe_msg = "Current directory is inside the folder."; + syscall(5, (uint32_t)not_safe_msg, 40, 0xF); + } // char invalid_flag_msg[] = "Recursive rm.\n"; // syscall(5, (uint32_t)invalid_flag_msg, 15, 0xF); From 7456521aaac91f30c65772ddd71022daa1200ff7 Mon Sep 17 00:00:00 2001 From: sozyGithub Date: Sat, 29 Apr 2023 22:15:32 +0700 Subject: [PATCH 098/101] resolve conflict --- src/user-shell.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index d500a09..8ca01df 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -959,7 +959,8 @@ bool is_rm_safe(struct CurrentDirectoryInfo *target_dir, struct ParseString fold uint16_t current_cluster_number = current_dir->current_cluster_number; uint32_t path_count = current_dir->current_path_count; - if (current_cluster_number == ROOT_CLUSTER_NUMBER) return TRUE; + if (current_cluster_number == ROOT_CLUSTER_NUMBER) + return TRUE; bool found = FALSE; do @@ -976,11 +977,10 @@ bool is_rm_safe(struct CurrentDirectoryInfo *target_dir, struct ParseString fold struct FAT32DirectoryTable *dir_table = request.buf; current_cluster_number = dir_table->table->cluster_low; path_count--; - found = (current_cluster_number == target_dir->current_cluster_number) - && (memcmp(current_dir->paths[path_count-1], name, DIRECTORY_NAME_LENGTH) == 0); + found = (current_cluster_number == target_dir->current_cluster_number) && (memcmp(current_dir->paths[path_count - 1], name, DIRECTORY_NAME_LENGTH) == 0); } - while(current_cluster_number != ROOT_CLUSTER_NUMBER && !found); + while (current_cluster_number != ROOT_CLUSTER_NUMBER && !found); if (found) { @@ -1344,7 +1344,7 @@ int main(void) else { - char not_safe_msg = "Current directory is inside the folder."; + char not_safe_msg[] = "Current directory is inside the folder."; syscall(5, (uint32_t)not_safe_msg, 40, 0xF); } } @@ -1372,7 +1372,7 @@ int main(void) else { - char not_safe_msg = "Current directory is inside the folder."; + char not_safe_msg[] = "Current directory is inside the folder."; syscall(5, (uint32_t)not_safe_msg, 40, 0xF); } // char invalid_flag_msg[] = "Recursive rm.\n"; @@ -1391,7 +1391,7 @@ int main(void) // get source directory info & source file name invoke_cd(buf, word_indexes + 1, &target_dir, &target_name); - if (is_rm_safe(&target_dir, target_name, ¤t_directory_info)) + if (is_rm_safe(&target_dir, target_name, ¤t_directory_info)) { // invoke rm command rm_command(&target_dir, &target_name, TRUE); @@ -1399,7 +1399,7 @@ int main(void) else { - char not_safe_msg = "Current directory is inside the folder."; + char not_safe_msg[] = "Current directory is inside the folder."; syscall(5, (uint32_t)not_safe_msg, 40, 0xF); } From 942cf94552fa4398b2a2da68f854d27b6d79e33d Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Sat, 29 Apr 2023 22:56:48 +0700 Subject: [PATCH 099/101] fix: remove safety bug --- src/user-shell.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index 8ca01df..5306850 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -976,8 +976,8 @@ bool is_rm_safe(struct CurrentDirectoryInfo *target_dir, struct ParseString fold syscall(6, (uint32_t)&request, 0, 0); struct FAT32DirectoryTable *dir_table = request.buf; current_cluster_number = dir_table->table->cluster_low; - path_count--; found = (current_cluster_number == target_dir->current_cluster_number) && (memcmp(current_dir->paths[path_count - 1], name, DIRECTORY_NAME_LENGTH) == 0); + path_count--; } while (current_cluster_number != ROOT_CLUSTER_NUMBER && !found); @@ -1344,8 +1344,8 @@ int main(void) else { - char not_safe_msg[] = "Current directory is inside the folder."; - syscall(5, (uint32_t)not_safe_msg, 40, 0xF); + char not_safe_msg[] = "Working directory is inside the folder.\n"; + syscall(5, (uint32_t)not_safe_msg, 41, 0xF); } } } @@ -1372,8 +1372,8 @@ int main(void) else { - char not_safe_msg[] = "Current directory is inside the folder."; - syscall(5, (uint32_t)not_safe_msg, 40, 0xF); + char not_safe_msg[] = "Working directory is inside the folder.\n"; + syscall(5, (uint32_t)not_safe_msg, 41, 0xF); } // char invalid_flag_msg[] = "Recursive rm.\n"; // syscall(5, (uint32_t)invalid_flag_msg, 15, 0xF); @@ -1399,8 +1399,8 @@ int main(void) else { - char not_safe_msg[] = "Current directory is inside the folder."; - syscall(5, (uint32_t)not_safe_msg, 40, 0xF); + char not_safe_msg[] = "Working directory is inside the folder.\n"; + syscall(5, (uint32_t)not_safe_msg, 41, 0xF); } // char invalid_flag_msg[] = "Recursive rm.\n"; From d9f0971ee1f5ae14c96c515b7eb6e8645e0304bb Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Sat, 29 Apr 2023 23:04:54 +0700 Subject: [PATCH 100/101] feat: add move checking --- src/user-shell.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index 5306850..6e5a2d8 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -1456,8 +1456,18 @@ int main(void) // get destination directory info & source file name invoke_cd(buf, word_indexes + 2, &dest_dir, &dest_name); - // invoke mv command - mv_command(&source_dir, &source_name, &dest_dir, &dest_name); + if (is_rm_safe(&source_dir, source_name, ¤t_directory_info)) + { + // invoke mv command + mv_command(&source_dir, &source_name, &dest_dir, &dest_name); + } + + else + { + char not_safe_msg[] = "Working directory is inside the folder.\n"; + syscall(5, (uint32_t)not_safe_msg, 41, 0xF); + } + } else { From 83e1998a3cca2b0e0f439482915d642391036f5c Mon Sep 17 00:00:00 2001 From: Enliven26 <16521443@mahasiswa.itb.ac.id> Date: Sat, 29 Apr 2023 23:23:54 +0700 Subject: [PATCH 101/101] feat: add cp folder --- src/user-shell.c | 64 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 3 deletions(-) diff --git a/src/user-shell.c b/src/user-shell.c index 6e5a2d8..e88ac17 100644 --- a/src/user-shell.c +++ b/src/user-shell.c @@ -875,7 +875,7 @@ uint8_t cp_command(struct CurrentDirectoryInfo *source_dir, splitcode = split_filename_extension(dest_name, &name, &ext); if (splitcode == 2 || splitcode == 3) { - char msg[] = "Source file not found.\n"; + char msg[] = "Source file/folder not found.\n"; syscall(5, (uint32_t)msg, 24, 0xF); // return; } @@ -927,7 +927,65 @@ uint8_t cp_command(struct CurrentDirectoryInfo *source_dir, else { - if (retcode == 2) + // find folder + read_request.buffer_size = CLUSTER_SIZE * MAX_FOLDER_CLUSTER_SIZE; + + // copy folder to buffer memory + syscall(1, (uint32_t)&read_request, (uint32_t)&retcode, 0); + + if (retcode == 0) + { + // read file to buffer success + /* WRITING STAGE */ + + // split source filename to name and extension + splitcode = split_filename_extension(dest_name, &name, &ext); + if (splitcode == 2 || splitcode == 3) + { + char msg[] = "Source file/folder not found.\n"; + syscall(5, (uint32_t)msg, 24, 0xF); + // return; + } + + // prepare write file request + struct FAT32DriverRequest write_request = { + .buf = cl, + .name = EMPTY_NAME, + .ext = EMPTY_EXTENSION, + .parent_cluster_number = dest_dir->current_cluster_number, + .buffer_size = 0, + }; + + memcpy(write_request.name, name.word, name.length); + memcpy(write_request.ext, ext.word, ext.length); + + // copy file from memory to disk + syscall(2, (uint32_t)&write_request, (uint32_t)&retcode, 0); + + if (retcode) + { + if (retcode == 1) + { + char msg[] = "File/folder already exists.\n"; + syscall(5, (uint32_t)msg, 29, 0xF); + } + + else if (retcode == 3) + { + char msg[] = "Forbidden file/folder name.\n"; + syscall(5, (uint32_t)msg, 29, 0xF); + } + + else + { + char msg[] = "Unknown error.\n"; + syscall(5, (uint32_t)msg, 16, 0xF); + } + return 2; + } + } + + else if (retcode == 2) { char msg[] = "Not enough buffer.\n"; syscall(5, (uint32_t)msg, 20, 0xF); @@ -1467,8 +1525,8 @@ int main(void) char not_safe_msg[] = "Working directory is inside the folder.\n"; syscall(5, (uint32_t)not_safe_msg, 41, 0xF); } - } + else { syscall(5, (uint32_t)too_many_args_msg, 20, 0xF);