diff --git a/Makefile b/Makefile index 9e3dd2d..9c34faf 100644 --- a/Makefile +++ b/Makefile @@ -32,12 +32,9 @@ GRUB_CONFIG := $(ARCH_DIR)/build/grub.cfg # sources C_SOURCES := $(shell find $(SRC_DIR) -type f -name '*.c' ! -name '*.excluded.c') -CPP_SOURCES := $(shell find $(SRC_DIR) -type f -name '*.cpp' ! -name '*.excluded.cpp') ASM_SOURCES := $(shell find $(SRC_DIR) -type f -name '*.asm') # filtered sources -# assuming C++ is only in src/apps, so there is no need -# to exclude it based on architecture C_SOURCES_FILTERED := \ $(filter-out $(SRC_DIR)/arch/%,$(C_SOURCES)) \ $(filter $(SRC_DIR)/arch/$(ARCH)/%,$(C_SOURCES)) @@ -47,11 +44,10 @@ ASM_SOURCES_FILTERED := \ # objects C_OBJECTS := $(patsubst $(SRC_DIR)/%.c,$(BIN_DIR)/%.o,$(C_SOURCES_FILTERED)) -CPP_OBJECTS := $(patsubst $(SRC_DIR)/%.cpp,$(BIN_DIR)/%.o,$(CPP_SOURCES)) ASM_OBJECTS := $(patsubst $(SRC_DIR)/%.asm,$(BIN_DIR)/%.o,$(ASM_SOURCES_FILTERED)) # all objects -OBJECTS := $(C_OBJECTS) $(CPP_OBJECTS) $(ASM_OBJECTS) +OBJECTS := $(C_OBJECTS) $(ASM_OBJECTS) # main target all: build_kernel build_iso @@ -61,13 +57,7 @@ all: build_kernel build_iso $(BIN_DIR)/%.o: $(SRC_DIR)/%.c @mkdir -p $(dir $@) @echo -e "\033[1;36m[*]\033[0m $< -> $@" - @gcc -g -Wall -Wextra -m$(ARCH_M) -ffreestanding -nostartfiles -Iinclude -nostdlib -fno-stack-protector -c $< -o $@ - -# build c++ sources -$(BIN_DIR)/%.o: $(SRC_DIR)/%.cpp - @mkdir -p $(dir $@) - @echo -e "\033[1;36m[*]\033[0m $< -> $@" - @g++ -g -Wall -Wextra -m$(ARCH_M) -ffreestanding -fno-rtti -fno-threadsafe-statics -nostartfiles -Iinclude -nostdlib -fno-stack-protector -fno-exceptions -c $< -o $@ + @gcc -g -Wall -Wextra -m$(ARCH_M) -mno-sse -mno-sse2 -mno-sse3 -mno-mmx -ffreestanding -nostartfiles -Iinclude -nostdlib -fno-stack-protector -c $< -o $@ # build assembly sources $(BIN_DIR)/%.o: $(SRC_DIR)/%.asm diff --git a/compile_flags.txt b/compile_flags.txt index f64628c..edfe2f5 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -7,3 +7,7 @@ -fno-stack-protector -fno-exceptions -fno-rtti +-mno-sse +-mno-sse2 +-mno-sse3 +-mno-mmx diff --git a/include/apps/calc.h b/include/apps/calc.h new file mode 100644 index 0000000..f523b6d --- /dev/null +++ b/include/apps/calc.h @@ -0,0 +1 @@ +void calculator_main(); diff --git a/include/apps/calc.hpp b/include/apps/calc.hpp deleted file mode 100644 index d4298e8..0000000 --- a/include/apps/calc.hpp +++ /dev/null @@ -1 +0,0 @@ -extern "C" void calculator_main(); diff --git a/include/apps/tinypad.h b/include/apps/tinypad.h new file mode 100644 index 0000000..b76450e --- /dev/null +++ b/include/apps/tinypad.h @@ -0,0 +1,7 @@ +#pragma once + +#include +#include +#include + +int tinypad_main(uint8_t color, uint8_t barcolor); diff --git a/include/apps/tinypad.hpp b/include/apps/tinypad.hpp deleted file mode 100644 index 6e88750..0000000 --- a/include/apps/tinypad.hpp +++ /dev/null @@ -1,19 +0,0 @@ -/** - * ------------------------------------------------------------------------- - * AurorOS - * (c) 2022-2025 Interpuce - * - * You should receive AurorOS license with this source code. If not - check: - * https://github.com/Interpuce/AurorOS/blob/main/LICENSE.md - * ------------------------------------------------------------------------- - */ - -#pragma once - -extern "C" { - #include - #include - #include -} - -int tinypad_main(uint8_t color, uint8_t barcolor); diff --git a/src/apps/calc/calc.cpp b/src/apps/calc/calc.c similarity index 91% rename from src/apps/calc/calc.cpp rename to src/apps/calc/calc.c index 9feadb2..c4a7736 100644 --- a/src/apps/calc/calc.cpp +++ b/src/apps/calc/calc.c @@ -1,12 +1,10 @@ -extern "C" { - #include - #include - #include - #include - #include -} +#include +#include +#include +#include +#include -extern "C" void calculator_main() { +void calculator_main() { int64_t left; int64_t right; char sign[2]; // leaving a space for a null-terminator diff --git a/src/apps/shell/commands/commands.c b/src/apps/shell/commands/commands.c new file mode 100644 index 0000000..7bfaf3b --- /dev/null +++ b/src/apps/shell/commands/commands.c @@ -0,0 +1,312 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void shc_cowsay(char message[1024]) { + int message_length = strlen(message); + print(" ", 0x07); + for (int i = 0; i < message_length + 2; i++) { + printchar('-', 0x07); + } + println("", 0x07); + print(" < ", 0x07); + print(message, 0x07); + print(" > \n", 0x07); + print(" ", 0x07); + for (int i = 0; i < message_length + 2; i++) { + printchar('-', 0x07); + } + println("", 0x07); + print(" \\ ^__^\n", 0x07); + print(" \\ (oo)\\_______\n", 0x07); + print(" (__)\\ )\\/\n", 0x07); + print(" ||---w||\n", 0x07); + print(" || ||\n", 0x07); +} +void shc_map() { + print("\n", 0x07); + print(" 0x01", 0x01); print(" 0x09", 0x09); + print(" 0x10", 0x10); print(" 0x90", 0x90); + print("\n", 0x07); + print(" 0x02", 0x02); print(" 0x0A", 0x0A); + print(" 0x20", 0x20); print(" 0xA0", 0xA0); + print("\n", 0x07); + print(" 0x03", 0x03); print(" 0x0B", 0x0B); + print(" 0x30", 0x30); print(" 0xB0", 0xB0); + print("\n", 0x07); + print(" 0x04", 0x04); print(" 0x0C", 0x0C); + print(" 0x40", 0x40); print(" 0xC0", 0xC0); + print("\n", 0x07); + print(" 0x05", 0x05); print(" 0x0D", 0x0D); + print(" 0x50", 0x50); print(" 0xD0", 0xD0); + print("\n", 0x07); + print(" 0x06", 0x06); print(" 0x0E", 0x0E); + print(" 0x60", 0x60); print(" 0xE0", 0xE0); + print("\n", 0x07); + print(" 0x07", 0x07); print(" 0x0F", 0x0F); + print(" 0x70", 0x70); print(" 0xF0", 0xF0); + print("\n", 0x07); + print(" 0x08", 0x08); print(" 0x00", 0x00); + print(" 0x80", 0x80); print(" 0x00", 0x00); + println("\n", 0x07); + print(" ~!@#$%^&*()_+ `1234567890-= \n", 0x0F); + print(" qwertyuiop[]\\ QWERTYUIOP{}| \n", 0x0F); + print(" asdfghjkl;' ASDFGHJKL:\" \n", 0x0F); + print(" zxcvbnm,./ ZXCVBNM<>? \n", 0x0F); + print("\n", 0x07); +} +void shc_eclair(const char *trt) { + if (streql(trt, "1")) { + print("\n", 0x07); + for (uint8_t i = 0; i < 128; i++) { + print(" ", 0x07); + print("Hello, world! ", i); + } + print("\n", 0x07); + } else if (streql(trt, "2")) { + paintscreen(0x91); + } else { + print_error("Invalid treatment argument provided!"); + } +} +void shc_help() { + println("", 0x07); + println(" ver - displays OS version info", 0x07); + println(" print - prints out ", 0x07); + println(" map - prints out every VGA color and every printable character in aurorOS", 0x07); + println(" cowsay - displays ascii art of an cow saying ", 0x07); + println(" tinypad - opens a text editor", 0x07); + println(" eclair - a little development command", 0x07); + println(" repo - get the AurorOS repo", 0x07); + println(" reboot - reboots the computer (works only in QEMU)", 0x07); + println(" shutdown - shuts down the computer (works only in QEMU)", 0x07); + println(" ls - shows all files in the current directory", 0x07); + println(" cat - reads a specified file", 0x07); + println(" cd - changes the directory", 0x07); + println(" chmod - changes permissions of a file", 0x07); + println(" exit - exits the shell or shuts down the OS", 0x07); + println(" calc - opens a calculator", 0x07); + println("", 0x07); +} +void shc_ls(fs_node* dir) { + if (!dir) return; + for (uint32_t i = 0; i < dir->child_count; i++) { + if (!dir->children[i]) continue; + print((const char*)dir->children[i]->name, 0x07); + print(" ", 0x07); + } + println("", 0x07); +} +void shc_cd(fs_node** current_dir, char* where, uint64_t current_user) { + if (!where || where[0] == 0) { + print_error("Missing operand"); + return; + } + + fs_node* target = fs_resolve(where, *current_dir); + if (!target) { + print_error("Directory not found"); + return; + } + + if (target->type != EMULATED_FS_DIR) { + print_info("Not a directory"); + return; + } + + int is_owner = target->owner == current_user; + + uint8_t perms = GET_PERMS(is_owner, is_owner, target->permissions); + if (!(perms & 0x1)) { + print_error("Permission denied"); + return; + } + + *current_dir = target; +} +uint16_t octal_to_uint16(const char* str) { + uint16_t result = 0; + for (int i = 0; str[i]; ++i) { + char c = str[i]; + if (c < '0' || c > '7') break; + result = (result << 3) | (c - '0'); + } + return result; +} +void shc_chmod(fs_node* current_dir, uint64_t current_user_id, char* perm_arg, char* target_path) { + if (!perm_arg || !target_path) { + print_error("Missing operand"); + return; + } + + fs_node* target = fs_resolve(target_path, current_dir); + if (!target) { + print_error("File not found"); + return; + } + + int is_owner = current_user_id == target->owner; + int is_root = current_user_id == 0; + + if (!is_owner && !is_root) { + print_error("Permission denied"); + return; + } + + uint16_t perms = target->permissions; + if (perm_arg[0] >= '0' && perm_arg[0] <= '7') { + uint16_t new_perms = octal_to_uint16(perm_arg); + target->permissions = new_perms; + return; + } + for (int i = 0; perm_arg[i]; ++i) { + if (perm_arg[i] == '+' || perm_arg[i] == '-') { + char op = perm_arg[i]; + ++i; + while (perm_arg[i]) { + uint8_t mask = 0; + switch (perm_arg[i]) { + case 'r': mask = 0x4; break; + case 'w': mask = 0x2; break; + case 'x': mask = 0x1; break; + } + if (op == '+') perms |= mask; + else perms &= ~mask; + ++i; + } + break; + } + } + + target->permissions = perms; + print_info("Permissions updated"); +} +void shc_cat(fs_node* current_dir, char* where, uint64_t current_user_id) { + if (!where || where[0] == 0) { + print_error("Missing operand"); + return; + } + fs_node* f = fs_resolve(where, current_dir); + if (!f) { + return print_error("File does not exist"); + } + if (f->type != EMULATED_FS_FILE) { + return print_info("Is a directory"); + } + + int is_owner = f->owner == current_user_id; + + uint8_t perms = GET_PERMS(is_owner, is_owner, f->permissions); + if (!(perms & 0x4)) { + print_error("Permission denied"); + return; + } + println_limit((char*)f->data, f->size, 0x07); +} +const char* fs_basename(const char* path) { + int len = 0; + while (path[len]) len++; + if (len == 0) return path; + int i = len - 1; + while (i >= 0 && path[i] == '/') i--; + if (i < 0) return path; + while (i >= 0 && path[i] != '/') i--; + return path + i + 1; +} +void shc_mkdir(fs_node* current_dir, const char* where, uint64_t owner) { + if (!where || where[0] == 0) { + print_error("Missing operand"); + return; + } + const char* name = fs_basename(where); + if (!name || name[0] == 0) { + print_error("Invalid name"); + return; + } + fs_node* existing = fs_resolve(where, current_dir); + if (existing) { + print_error("Cannot create directory: already exists"); + return; + } + fs_node* parent = current_dir; + int last_slash = -1; + for (int i = 0; where[i]; i++) { + if (where[i] == '/') last_slash = i; + } + if (last_slash >= 0) { + if (last_slash == 0) { + parent = fs_resolve("/", current_dir); + } else { + char buffer[256]; + int len = last_slash; + if (len > 255) len = 255; + for (int i = 0; i < len; i++) buffer[i] = where[i]; + buffer[len] = 0; + parent = fs_resolve(buffer, current_dir); + } + if (!parent) { + print_error("Directory parent error: parent does not exist"); + return; + } + if (parent->type != EMULATED_FS_DIR) { + print_error("Directory parent error: not a directory"); + return; + } + } + fs_node* new_dir = fs_create_dir_node(name, parent, owner); + fs_add_child(parent, new_dir); +} +void shc_rm(fs_node* current_dir, const char* path) { + if (!path || path[0] == 0) { + print_error("Missing operand"); + return; + } + fs_node* node = fs_resolve(path, current_dir); + if (!node) { + print_error("No such file or directory"); + return; + } + if (node->type == EMULATED_FS_DIR) { + kbool confirmation = read_yn("Are you sure you want to delete a directory?\n (y/n) $ ", 0x07); + if (confirmation == KFALSE) return print_info("Ommitting directory"); + } + fs_node* parent = node->parent; + if (!parent) { + print_error("It is dangerous to operate recursively on '/'"); + print_error("If possible, please reformat the drive instead of using this command."); + return; + } + fs_remove_child(parent, node); + fs_delete(node); +} +const char* shc_pwd(fs_node* current_dir) { + static char path[256]; + int pos = 255; + path[pos] = '\0'; + fs_node* node = current_dir; + while (node != NULL) { + if (node->parent == NULL) { + //path[--pos] = '/'; + break; + } + int len = 0; + while (node->name[len] != '\0') len++; + for (int i = len - 1; i >= 0; i--) { + path[--pos] = node->name[i]; + } + path[--pos] = '/'; + node = node->parent; + } + const char* returnable = &path[pos]; + if (streql(returnable, "")) { + returnable = "/"; + } + return returnable; +} diff --git a/src/apps/shell/commands/commands.cpp b/src/apps/shell/commands/commands.cpp deleted file mode 100644 index fbf52ed..0000000 --- a/src/apps/shell/commands/commands.cpp +++ /dev/null @@ -1,364 +0,0 @@ -#pragma GCC optimize ("O3") - -extern "C" { - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include -} - -namespace ShellCommands { - void cowsay(char message[1024]) { - int message_length = strlen(message); - - print(" ", 0x07); - for (int i = 0; i < message_length + 2; i++) { - printchar('-', 0x07); - } - println("", 0x07); - - print(" < ", 0x07); - print(message, 0x07); - print(" > \n", 0x07); - - print(" ", 0x07); - for (int i = 0; i < message_length + 2; i++) { - printchar('-', 0x07); - } - println("", 0x07); - - print(" \\ ^__^\n", 0x07); - print(" \\ (oo)\\_______\n", 0x07); - print(" (__)\\ )\\/\n", 0x07); - print(" ||---w||\n", 0x07); - print(" || ||\n", 0x07); - } - - void map() { - print("\n", 0x07); - print(" 0x01", 0x01); print(" 0x09", 0x09); - print(" 0x10", 0x10); print(" 0x90", 0x90); - print("\n", 0x07); - print(" 0x02", 0x02); print(" 0x0A", 0x0A); - print(" 0x20", 0x20); print(" 0xA0", 0xA0); - print("\n", 0x07); - print(" 0x03", 0x03); print(" 0x0B", 0x0B); - print(" 0x30", 0x30); print(" 0xB0", 0xB0); - print("\n", 0x07); - print(" 0x04", 0x04); print(" 0x0C", 0x0C); - print(" 0x40", 0x40); print(" 0xC0", 0xC0); - print("\n", 0x07); - print(" 0x05", 0x05); print(" 0x0D", 0x0D); - print(" 0x50", 0x50); print(" 0xD0", 0xD0); - print("\n", 0x07); - print(" 0x06", 0x06); print(" 0x0E", 0x0E); - print(" 0x60", 0x60); print(" 0xE0", 0xE0); - print("\n", 0x07); - print(" 0x07", 0x07); print(" 0x0F", 0x0F); - print(" 0x70", 0x70); print(" 0xF0", 0xF0); - print("\n", 0x07); - print(" 0x08", 0x08); print(" 0x00", 0x00); - print(" 0x80", 0x80); print(" 0x00", 0x00); - println("\n", 0x07); - print(" ~!@#$%^&*()_+ `1234567890-= \n", 0x0F); - print(" qwertyuiop[]\\ QWERTYUIOP{}| \n", 0x0F); - print(" asdfghjkl;' ASDFGHJKL:\" \n", 0x0F); - print(" zxcvbnm,./ ZXCVBNM<>? \n", 0x0F); - print("\n", 0x07); - } - - void eclair(const char *trt) { - if (streql(trt, "1")) { - print("\n", 0x07); - for (uint8_t i = 0; i < 128; i++) { - print(" ", 0x07); - print("Hello, world! ", i); - } - print("\n", 0x07); - } else if (streql(trt, "2")) { - paintscreen(0x91); - } else { - print_error("Invalid treatment argument provided!"); - } - } - - void help() { - println("", 0x07); - println(" ver - displays OS version info", 0x07); - println(" print - prints out ", 0x07); - println(" map - prints out every VGA color and every printable character in aurorOS", 0x07); - println(" cowsay - displays ascii art of an cow saying ", 0x07); - println(" tinypad - opens a text editor", 0x07); - println(" eclair - a little development command", 0x07); - println(" repo - get the AurorOS repo", 0x07); - println(" reboot - reboots the computer (works only in QEMU)", 0x07); - println(" shutdown - shuts down the computer (works only in QEMU)", 0x07); - println(" ls - shows all files in the current directory", 0x07); - println(" cat - reads a specified file", 0x07); - println(" cd - changes the directory", 0x07); - println(" chmod - changes permissions of a file", 0x07); - println(" exit - exits the shell or shuts down the OS", 0x07); - println(" calc - opens a calculator", 0x07); - println("", 0x07); - } - - void ls(fs_node* dir) { - if (!dir) return; - - for (uint32_t i = 0; i < dir->child_count; i++) { - if (!dir->children[i]) continue; - - print((const char*)dir->children[i]->name, 0x07); - print(" ", 0x07); - } - - println("", 0x07); - } - - void cd(fs_node** current_dir, char* where, uint64_t current_user) { - if (!where || where[0] == 0) { - print_error("Missing operand"); - return; - } - - fs_node* target = fs_resolve(where, *current_dir); - if (!target) { - print_error("Directory not found"); - return; - } - - if (target->type != EMULATED_FS_DIR) { - print_info("Not a directory"); - return; - } - - int is_owner = target->owner == current_user; - - uint8_t perms = GET_PERMS(is_owner, is_owner, target->permissions); - if (!(perms & 0x1)) { - print_error("Permission denied"); - return; - } - - *current_dir = target; - } - - uint16_t octal_to_uint16(const char* str) { - uint16_t result = 0; - for (int i = 0; str[i]; ++i) { - char c = str[i]; - if (c < '0' || c > '7') break; - result = (result << 3) | (c - '0'); - } - return result; - } - - void chmod(fs_node* current_dir, uint64_t current_user_id, char* perm_arg, char* target_path) { - if (!perm_arg || !target_path) { - print_error("Missing operand"); - return; - } - - fs_node* target = fs_resolve(target_path, current_dir); - if (!target) { - print_error("File not found"); - return; - } - - int is_owner = current_user_id == target->owner; - int is_root = current_user_id == 0; - - if (!is_owner && !is_root) { - print_error("Permission denied"); - return; - } - - uint16_t perms = target->permissions; - - if (perm_arg[0] >= '0' && perm_arg[0] <= '7') { - uint16_t new_perms = ShellCommands::octal_to_uint16(perm_arg); - target->permissions = new_perms; - return; - } - - for (int i = 0; perm_arg[i]; ++i) { - if (perm_arg[i] == '+' || perm_arg[i] == '-') { - char op = perm_arg[i]; - ++i; - while (perm_arg[i]) { - uint8_t mask = 0; - switch (perm_arg[i]) { - case 'r': mask = 0x4; break; - case 'w': mask = 0x2; break; - case 'x': mask = 0x1; break; - } - if (op == '+') perms |= mask; - else perms &= ~mask; - ++i; - } - break; - } - } - - target->permissions = perms; - print_info("Permissions updated"); - } - - void cat(fs_node* current_dir, char* where, uint64_t current_user_id) { - if (!where || where[0] == 0) { - print_error("Missing operand"); - return; - } - - fs_node* f = fs_resolve(where, current_dir); - - if (!f) { - return print_error("File does not exist"); - } - if (f->type != EMULATED_FS_FILE) { - return print_info("Is a directory"); - } - - int is_owner = f->owner == current_user_id; - - uint8_t perms = GET_PERMS(is_owner, is_owner, f->permissions); - if (!(perms & 0x4)) { - print_error("Permission denied"); - return; - } - - println_limit((char*)f->data, f->size, 0x07); - } - - const char* fs_basename(const char* path) { - int len = 0; - while (path[len]) len++; - if (len == 0) return path; - - int i = len - 1; - while (i >= 0 && path[i] == '/') i--; - if (i < 0) return path; - while (i >= 0 && path[i] != '/') i--; - - return path + i + 1; - } - - void mkdir(fs_node* current_dir, const char* where, uint64_t owner) { - if (!where || where[0] == 0) { - print_error("Missing operand"); - return; - } - - const char* name = fs_basename(where); - if (!name || name[0] == 0) { - print_error("Invalid name"); - return; - } - - fs_node* existing = fs_resolve(where, current_dir); - if (existing) { - print_error("Cannot create directory: already exists"); - return; - } - - fs_node* parent = current_dir; - int last_slash = -1; - - for (int i = 0; where[i]; i++) { - if (where[i] == '/') last_slash = i; - } - - if (last_slash >= 0) { - if (last_slash == 0) { - parent = fs_resolve("/", current_dir); - } else { - char buffer[256]; - int len = last_slash; - if (len > 255) len = 255; - for (int i = 0; i < len; i++) buffer[i] = where[i]; - buffer[len] = 0; - parent = fs_resolve(buffer, current_dir); - } - - if (!parent) { - print_error("Directory parent error: parent does not exist"); - return; - } - - if (parent->type != EMULATED_FS_DIR) { - print_error("Directory parent error: not a directory"); - return; - } - } - - fs_node* new_dir = fs_create_dir_node(name, parent, owner); - fs_add_child(parent, new_dir); - } - - void rm(fs_node* current_dir, const char* path) { - if (!path || path[0] == 0) { - print_error("Missing operand"); - return; - } - - fs_node* node = fs_resolve(path, current_dir); - if (!node) { - print_error("No such file or directory"); - return; - } - - if (node->type == EMULATED_FS_DIR) { - kbool confirmation = read_yn("Are you sure you want to delete a directory?\n (y/n) $ ", 0x07); - if (confirmation == KFALSE) return print_info("Ommitting directory"); - } - - fs_node* parent = node->parent; - if (!parent) { - print_error("It is dangerous to operate recursively on '/'"); - print_error("If possible, please reformat the drive instead of using this command."); - return; - } - - fs_remove_child(parent, node); - fs_delete(node); - } - - const char* pwd(fs_node* current_dir) { - static char path[256]; - int pos = 255; - path[pos] = '\0'; - - fs_node* node = current_dir; - - while (node != NULL) { - if (node->parent == NULL) { - //path[--pos] = '/'; - break; - } - - int len = 0; - while (node->name[len] != '\0') len++; - - for (int i = len - 1; i >= 0; i--) { - path[--pos] = node->name[i]; - } - - path[--pos] = '/'; - node = node->parent; - } - - const char* returnable = &path[pos]; - - if (streql(returnable, "")) { - returnable = "/"; - } - - return returnable; - } -} diff --git a/src/apps/shell/commands/commands.h b/src/apps/shell/commands/commands.h new file mode 100644 index 0000000..63f8e45 --- /dev/null +++ b/src/apps/shell/commands/commands.h @@ -0,0 +1,17 @@ +#pragma once + +#include +#include +#include + +extern void shc_cowsay(char message[1024]); +extern void shc_map(); +extern void shc_eclair(const char *trt); +extern void shc_help(); +extern void shc_cat(fs_node* current_dir, char* where, uint64_t current_user_id); +extern void shc_cd(fs_node** current_dir, char* where, uint64_t current_user); +extern void shc_ls(fs_node* dir); +extern const char* shc_pwd(fs_node* current_dir); +extern void shc_mkdir(fs_node* current_dir, const char* where, uint64_t owner); +extern void shc_rm(fs_node* current_dir, const char* path); +extern void shc_chmod(fs_node* current_dir, uint64_t current_user_id, char* perm_arg, char* target_path); diff --git a/src/apps/shell/commands/commands.hpp b/src/apps/shell/commands/commands.hpp deleted file mode 100644 index 0933de7..0000000 --- a/src/apps/shell/commands/commands.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace ShellCommands { - extern void cowsay(char message[1024]); - extern void map(); - extern void eclair(const char *trt); - extern void help(); - extern void cat(fs_node* current_dir, char* where, uint64_t current_user_id); - extern void cd(fs_node** current_dir, char* where, uint64_t current_user); - extern void ls(fs_node* dir); - extern const char* pwd(fs_node* current_dir); - extern void mkdir(fs_node* current_dir, const char* where, uint64_t owner); - extern void rm(fs_node* current_dir, const char* path); - extern void chmod(fs_node* current_dir, uint64_t current_user_id, char* perm_arg, char* target_path); -} diff --git a/src/apps/shell/sh.c b/src/apps/shell/sh.c new file mode 100644 index 0000000..8b17eed --- /dev/null +++ b/src/apps/shell/sh.c @@ -0,0 +1,173 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "commands/commands.h" +#include +#include + +int shell_main(uint16_t theme, char* current_user, uint64_t user_id); + +void shell_printprefix(const char* user, const char* pcname, const char* directory) { + char home[256]; + int pos = 0; + + if (streql(user, "root")) { + const char* base = "/root"; + for (int i = 0; base[i] && pos < 255; i++) + home[pos++] = base[i]; + home[pos] = 0; + } else { + const char* base = "/home/"; + for (int i = 0; base[i] && pos < 255; i++) + home[pos++] = base[i]; + for (int i = 0; user[i] && pos < 255; i++) + home[pos++] = user[i]; + home[pos] = 0; + } + + const char* shown = directory; + int match = 1; + + for (int i = 0; home[i]; i++) { + if (directory[i] != home[i]) { + match = 0; + break; + } + } + + if (match) { + shown = "~"; + } + + print(user, 0x0B); + print("@", 0x07); + print(pcname, 0x0B); + print(":", 0x07); + print(shown, 0x0B); + print(" $ ", 0x0F); +} + +typedef enum { + EvalResultNormal, + EvalResultExitShell, + EvalResultExitKernelMainLoop, + EvalResultRecursiveNormalExit +} EvalResult; + +EvalResult shell_evaluate_command(char* command, uint16_t theme, char* current_user, fs_node** current_dir, uint64_t user_id) { + char *args[10]; + int arg_count = split_str(command, ' ', args, 10); + + if (arg_count > 0) { + char farg[1024] = ""; + for (int i = 1; i < arg_count; i++) { + strcat(farg, args[i]); + strcat(farg, " "); + } + + if (streql(args[0], "ver")) { + print(" ", 0x07); + print(AUROR_NAME, 0x07); + print(" ", 0x07); + println(AUROR_VERSION, 0x07); + } else if (streql(args[0], "print")) { + println(farg ,0x07); + } else if (streql(args[0], "cowsay")) { + shc_cowsay(farg); + } else if (streql(args[0], "map")) { + shc_map(); + } else if (streql(args[0], "clear")) { + clearscreen(); + } else if (streql(args[0], "reboot")) { + reboot(); + } else if (streql(args[0], "shutdown")) { + shutdown(); + } else if (streql(args[0], "eclair")) { + shc_eclair(args[1]); + } else if (streql(args[0], "cat")) { + shc_cat(*current_dir, args[1], user_id); + } else if (streql(args[0], "cd")) { + shc_cd(current_dir, args[1], user_id); + } else if (streql(args[0], "ls")) { + shc_ls(*current_dir); + } else if (streql(args[0], "mkdir")) { + shc_mkdir(*current_dir, args[1], user_id); + } else if (streql(args[0], "rm")) { + shc_rm(*current_dir, args[1]); + } else if (streql(args[0], "tinypad")) { + tinypad_main(0x07, 0x9F); + } else if (streql(args[0], "help")) { + shc_help(); + } else if (streql(args[0], "repo")) { + println("Visit this link on other device:", 0x07); + println("https://github.com/Interpuce/AurorOS", 0x07); + } else if (streql(args[0], "sh")) { + if ( + shell_main(theme, current_user, user_id) == EvalResultRecursiveNormalExit + ) return EvalResultRecursiveNormalExit; + } else if (streql(args[0], "exit")) { + return EvalResultExitShell; + } else if (streql(args[0], "logout")) { + return EvalResultRecursiveNormalExit; + } else if (streql(args[0], "kptesting") && AUROR_BETA_STATE != 0) { + return EvalResultExitKernelMainLoop; + } else if (streql(args[0], "eval")) { + return shell_evaluate_command(farg, theme, current_user, current_dir, user_id); + } else if (streql(args[0], "pwd")) { + println(shc_pwd(*current_dir), 0x07); + } else if (streql(args[0], "chmod")) { + if (!args[1] || !args[2]) { + print_error("Usage: chmod +rwx/700 file"); + return EvalResultNormal; + } + shc_chmod(*current_dir, user_id, args[1], args[2]); + } else if (streql(args[0], "id")) { + char buffer[25]; + utoa(user_id, buffer, 1); + println(buffer, 0x07); + } else if (streql(args[0], "calc")) { + calculator_main(); + } else { + char* error = strcat(args[0], " is neither a known command nor valid AEF binary!"); + print_error(error); + } + } + return EvalResultNormal; +} + +int shell_main(uint16_t theme, char* current_user, uint64_t user_id) { + char user_home_path[256] = ""; + strcpy(user_home_path, "/home/"); + strcat(user_home_path, current_user); + fs_node* current_dir = fs_resolve(streql(current_user, "root") ? "root" : user_home_path, emulated_fs_root); + + char buffer[128]; + while (KTRUE) { + shell_printprefix(current_user, PC_NAME, shc_pwd(current_dir)); + read_str(buffer, sizeof(buffer), 0, 0x07); + + EvalResult eval_result = shell_evaluate_command(buffer, theme, current_user, ¤t_dir, user_id); + + if (eval_result == EvalResultNormal) continue; + if (eval_result == EvalResultExitShell) return 0; + if (eval_result == EvalResultRecursiveNormalExit) return EvalResultRecursiveNormalExit; + + break; + } + + kernelpanic("KERNEL_MAIN_LOOP_EXITED", + "This shall not happen unless you're using\n" + " a developer command 'kptesting' on a beta build of AurorOS.\n" + " If this screen was not issued by that command, please report\n" + " an issue." + ); + return 1; +} diff --git a/src/apps/shell/sh.cpp b/src/apps/shell/sh.cpp deleted file mode 100644 index c8fc9a7..0000000 --- a/src/apps/shell/sh.cpp +++ /dev/null @@ -1,181 +0,0 @@ -#pragma GCC optimize ("O0") -#pragma GCC target ("no-sse") - -extern "C" { - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include -} - -#include "commands/commands.hpp" -#include -#include - -extern "C" int shell_main(uint16_t theme, char* current_user, uint64_t user_id); - -namespace ShellUtils { - void printprefix(const char* user, const char* pcname, const char* directory) { - char home[256]; - int pos = 0; - - if (streql(user, "root")) { - const char* base = "/root"; - for (int i = 0; base[i] && pos < 255; i++) - home[pos++] = base[i]; - home[pos] = 0; - } else { - const char* base = "/home/"; - for (int i = 0; base[i] && pos < 255; i++) - home[pos++] = base[i]; - for (int i = 0; user[i] && pos < 255; i++) - home[pos++] = user[i]; - home[pos] = 0; - } - - const char* shown = directory; - int match = 1; - - for (int i = 0; home[i]; i++) { - if (directory[i] != home[i]) { - match = 0; - break; - } - } - - if (match) { - shown = "~"; - } - - print(user, 0x0B); - print("@", 0x07); - print(pcname, 0x0B); - print(":", 0x07); - print(shown, 0x0B); - print(" $ ", 0x0F); - } - - namespace EvalCmdReturnType { - typedef enum { - Normal, - ExitShell, - ExitKernelMainLoop, - RecursiveNormalExit - } Type; - } - - EvalCmdReturnType::Type evaluate_command(char* command, uint16_t theme, char* current_user, fs_node** current_dir, uint64_t user_id) { - char *args[10]; - int arg_count = split_str(command, ' ', args, 10); - - if (arg_count > 0) { - char farg[1024] = ""; - for (int i = 1; i < arg_count; i++) { - strcat(farg, args[i]); - strcat(farg, " "); - } - - if (streql(args[0], "ver")) { - print(" ", 0x07); - print(AUROR_NAME, 0x07); - print(" ", 0x07); - println(AUROR_VERSION, 0x07); - } else if (streql(args[0], "print")) { - println(farg ,0x07); - } else if (streql(args[0], "cowsay")) { - ShellCommands::cowsay(farg); - } else if (streql(args[0], "map")) { - ShellCommands::map(); - } else if (streql(args[0], "clear")) { - clearscreen(); - } else if (streql(args[0], "reboot")) { - reboot(); - } else if (streql(args[0], "shutdown")) { - shutdown(); - } else if (streql(args[0], "eclair")) { - ShellCommands::eclair(args[1]); - } else if (streql(args[0], "cat")) { - ShellCommands::cat(*current_dir, args[1], user_id); - } else if (streql(args[0], "cd")) { - ShellCommands::cd(current_dir, args[1], user_id); - } else if (streql(args[0], "ls")) { - ShellCommands::ls(*current_dir); - } else if (streql(args[0], "mkdir")) { - ShellCommands::mkdir(*current_dir, args[1], user_id); - } else if (streql(args[0], "rm")) { - ShellCommands::rm(*current_dir, args[1]); - } else if (streql(args[0], "tinypad")) { - tinypad_main(0x07, 0x9F); - } else if (streql(args[0], "help")) { - ShellCommands::help(); - } else if (streql(args[0], "repo")) { - println("Visit this link on other device:", 0x07); - println("https://github.com/Interpuce/AurorOS", 0x07); - } else if (streql(args[0], "sh")) { - if (shell_main(theme, current_user, user_id) == EvalCmdReturnType::RecursiveNormalExit) return EvalCmdReturnType::RecursiveNormalExit; - } else if (streql(args[0], "exit")) { - return EvalCmdReturnType::ExitShell; - } else if (streql(args[0], "logout")) { - return EvalCmdReturnType::RecursiveNormalExit; - } else if (streql(args[0], "kptesting") && AUROR_BETA_STATE != 0) { - return EvalCmdReturnType::ExitKernelMainLoop; - } else if (streql(args[0], "eval")) { - return evaluate_command(farg, theme, current_user, current_dir, user_id); - } else if (streql(args[0], "pwd")) { - println(ShellCommands::pwd(*current_dir), 0x07); - } else if (streql(args[0], "chmod")) { - if (!args[1] || !args[2]) { - print_error("Usage: chmod +rwx/700 file"); - return EvalCmdReturnType::Normal; - } - ShellCommands::chmod(*current_dir, user_id, args[1], args[2]); - } else if (streql(args[0], "id")) { - char buffer[25]; - utoa(user_id, buffer, 1); - println(buffer, 0x07); - } else if (streql(args[0], "calc")) { - calculator_main(); - } else { - char* error = strcat(args[0], " is neither a known command nor valid AEF binary!"); - print_error(error); - } - } - return EvalCmdReturnType::Normal; - } -} - -extern "C" int shell_main(uint16_t theme, char* current_user, uint64_t user_id) { - char user_home_path[256] = ""; - strcpy(user_home_path, "/home/"); - strcat(user_home_path, current_user); - fs_node* current_dir = fs_resolve(streql(current_user, "root") ? "root" : user_home_path, emulated_fs_root); - - char buffer[128]; - while (KTRUE) { - ShellUtils::printprefix(current_user, PC_NAME, ShellCommands::pwd(current_dir)); - read_str(buffer, sizeof(buffer), 0, 0x07); - - ShellUtils::EvalCmdReturnType::Type eval_result = ShellUtils::evaluate_command(buffer, theme, current_user, ¤t_dir, user_id); - - using namespace ShellUtils::EvalCmdReturnType; - if (eval_result == Normal) continue; - if (eval_result == ExitShell) return 0; - if (eval_result == RecursiveNormalExit) return RecursiveNormalExit; - - break; - } - - kernelpanic("KERNEL_MAIN_LOOP_EXITED", - "This shall not happen unless you're using\n" - " a developer command 'kptesting' on a beta build of AurorOS.\n" - " If this screen was not issued by that command, please report\n" - " an issue." - ); - return 1; -} diff --git a/src/apps/terminal/tty.c b/src/apps/terminal/tty.c new file mode 100644 index 0000000..65bbc29 --- /dev/null +++ b/src/apps/terminal/tty.c @@ -0,0 +1,194 @@ +#pragma GCC optimize("O0") +#pragma GCC target ("no-sse") + +#include +#include +#include +#include +#include +#include +#include +typedef struct { + uint64_t user_id; + char username[32]; + char password[32]; + char groups[8][32]; + int group_count; +} UserEntry; + +void parse_users(const char* buf, int len, UserEntry* out, int* out_count) { + int i = 0; + *out_count = 0; + + while (i < len && *out_count < 16) { + UserEntry* ue = &out[*out_count]; + ue->username[0] = 0; + ue->password[0] = 0; + ue->group_count = 0; + ue->user_id = 0; + + int field = 0; // 0=user_id, 1=username, 2=password, 3=groups, 4=nothing + int char_i = 0; + int group_i = 0; + int group_char_i = 0; + + while (i < len && buf[i] != '\n') { + char c = buf[i]; + + if (c == ':') { + if (field == 1) ue->username[char_i] = 0; + else if (field == 2) ue->password[char_i] = 0; + else if (field == 3 && group_char_i > 0 && group_i < 8) { + ue->groups[group_i][group_char_i] = 0; + ue->group_count++; + group_i++; + group_char_i = 0; + } + char_i = 0; + field++; + } + else if (field == 3) { + if (c == ',' && group_i < 8) { + ue->groups[group_i][group_char_i] = 0; + ue->group_count++; + group_i++; + group_char_i = 0; + } else if (group_char_i < 31) { + ue->groups[group_i][group_char_i++] = c; + } + } + else if (field == 1 || field == 2) { + if (char_i < 31) { + if (field == 1) ue->username[char_i++] = c; + else ue->password[char_i++] = c; + } + } + else if (field == 0) { + if (c >= '0' && c <= '9') { + ue->user_id = ue->user_id * 10 + (c - '0'); + } + } + i++; + } + + if (field == 3 && group_char_i > 0 && group_i < 8) { + ue->groups[group_i][group_char_i] = 0; + ue->group_count++; + } + + (*out_count)++; + + if (i < len && buf[i] == '\n') i++; + } +} + +UserEntry* find_user(const char* name, UserEntry* users, int count) { + for (int i = 0; i < count; i++) { + if (streql(users[i].username, name)) { + return &users[i]; + } + } + return NULL; +} + +int shell_main(uint16_t theme, char* current_user, uint64_t user_id); + +int terminal_main(uint16_t theme) { + char buf[2048]; + UserEntry users[16]; + int users_count = 0; + +reauth: { + static kbool welcome_msg_displayed = KFALSE; + + fs_node* node = fs_resolve("/etc/users", fs_root); + if (!node) { + kernelpanic("USERS_MISSING", "Cannot read the users file (/etc/users)\n or it is invalid. Login aborted."); + goto reauth; + } + + int len = fs_read(node, (uint8_t*)buf, sizeof(buf)-1); + if (len < 0) { + kernelpanic("USERS_MISSING", "Cannot read the users file (/etc/users)\n or it is invalid. Login aborted."); + goto reauth; + } + buf[len] = 0; + + parse_users(buf, len, users, &users_count); + + if (welcome_msg_displayed == KFALSE) { + println("", 0x07); + + switch (AUROR_BETA_STATE) { + case 1: + print_warn("You are using early build of AurorOS!"); + break; + case 2: + print_warn("You are using public beta build of AurorOS!"); + break; + case 3: + print_warn("You are using release candidate build of AurorOS!"); + break; + default: + print_ok("You're running a stable version of AurorOS!"); + break; + } + + #if defined(__amd64__) || defined(__x86_64__) + print_warn("You are using an architecture that is experimental in AurorOS."); + #endif + + println("", 0x07); + println("Welcome to AurorOS!", 0x0a); + + if (find_user("liveuser", users, users_count) && AUROR_LIVEUSER_AUTOLOGIN) { + println("Automatic login is enabled for the liveuser account.", 0x07); + } + + println("", 0x07); + + welcome_msg_displayed = KTRUE; + } + + static char username[32] = {0}; + print("AurorOS login: ", 0x07); + read_str(username, sizeof(username), KFALSE, 0x07); + + if (username[0] == 0) { + println("", 0x07); + print_error("An username has to be provided."); + println("", 0x07); + goto reauth; + } + + UserEntry* user = find_user(username, users, users_count); + + char passwd[32] = {0}; + print(username, 0x07); + print("@", 0x07); + print(PC_NAME, 0x07); + print(" password: ", 0x07); + + if (user && streql(username, "liveuser") && AUROR_LIVEUSER_AUTOLOGIN == KTRUE) { + println("(automatic login)", 0x07); + } else { + read_str(passwd, sizeof(passwd), KTRUE, 0x07); + if (!user || !streql(passwd, user->password)) { + println("", 0x07); + print_error("Login incorrect"); + println("", 0x07); + goto reauth; + } + } + + println("", 0x07); + + shell_main(theme, user->username, user->user_id); + + println("", 0x07); + + goto reauth; +} + + return -1; +} diff --git a/src/apps/terminal/tty.cpp b/src/apps/terminal/tty.cpp deleted file mode 100644 index 671cd9c..0000000 --- a/src/apps/terminal/tty.cpp +++ /dev/null @@ -1,199 +0,0 @@ -#pragma GCC optimize("O0") -#pragma GCC target ("no-sse") - -extern "C" { - #include - #include - #include - #include - #include - #include - #include -} - -namespace Auth { - - typedef struct { - uint64_t user_id; - char username[32]; - char password[32]; - char groups[8][32]; - int group_count; - } UserEntry; - - void parse_users(const char* buf, int len, UserEntry* out, int* out_count) { - int i = 0; - *out_count = 0; - - while (i < len && *out_count < 16) { - UserEntry* ue = &out[*out_count]; - ue->username[0] = 0; - ue->password[0] = 0; - ue->group_count = 0; - ue->user_id = 0; - - int field = 0; // 0=user_id, 1=username, 2=password, 3=groups, 4=nothing - int char_i = 0; - int group_i = 0; - int group_char_i = 0; - - while (i < len && buf[i] != '\n') { - char c = buf[i]; - - if (c == ':') { - if (field == 1) ue->username[char_i] = 0; - else if (field == 2) ue->password[char_i] = 0; - else if (field == 3 && group_char_i > 0 && group_i < 8) { - ue->groups[group_i][group_char_i] = 0; - ue->group_count++; - group_i++; - group_char_i = 0; - } - char_i = 0; - field++; - } - else if (field == 3) { - if (c == ',' && group_i < 8) { - ue->groups[group_i][group_char_i] = 0; - ue->group_count++; - group_i++; - group_char_i = 0; - } else if (group_char_i < 31) { - ue->groups[group_i][group_char_i++] = c; - } - } - else if (field == 1 || field == 2) { - if (char_i < 31) { - if (field == 1) ue->username[char_i++] = c; - else ue->password[char_i++] = c; - } - } - else if (field == 0) { - if (c >= '0' && c <= '9') { - ue->user_id = ue->user_id * 10 + (c - '0'); - } - } - i++; - } - - if (field == 3 && group_char_i > 0 && group_i < 8) { - ue->groups[group_i][group_char_i] = 0; - ue->group_count++; - } - - (*out_count)++; - - if (i < len && buf[i] == '\n') i++; - } - } - - UserEntry* find_user(const char* name, UserEntry* users, int count) { - for (int i = 0; i < count; i++) { - if (streql(users[i].username, name)) { - return &users[i]; - } - } - return reinterpret_castNULL; - } -} - -extern "C" int shell_main(uint16_t theme, char* current_user, uint64_t user_id); - -extern "C" int terminal_main(uint16_t theme) { - char buf[2048]; - Auth::UserEntry users[16]; - int users_count = 0; - -reauth: - static kbool welcome_msg_displayed = KFALSE; - - fs_node* node = fs_resolve("/etc/users", fs_root); - if (!node) { - kernelpanic("USERS_MISSING", "Cannot read the users file (/etc/users)\n or it is invalid. Login aborted."); - goto reauth; - } - - int len = fs_read(node, (uint8_t*)buf, sizeof(buf)-1); - if (len < 0) { - kernelpanic("USERS_MISSING", "Cannot read the users file (/etc/users)\n or it is invalid. Login aborted."); - goto reauth; - } - buf[len] = 0; - - Auth::parse_users(buf, len, users, &users_count); - - if (welcome_msg_displayed == KFALSE) { - println("", 0x07); - - switch (AUROR_BETA_STATE) { - case 1: - print_warn("You are using early build of AurorOS!"); - break; - case 2: - print_warn("You are using public beta build of AurorOS!"); - break; - case 3: - print_warn("You are using release candidate build of AurorOS!"); - break; - default: - print_ok("You're running a stable version of AurorOS!"); - break; - } - - #if defined(__amd64__) || defined(__x86_64__) - print_warn("You are using an architecture that is experimental in AurorOS."); - #endif - - println("", 0x07); - println("Welcome to AurorOS!", 0x0a); - - if (Auth::find_user("liveuser", users, users_count) && AUROR_LIVEUSER_AUTOLOGIN) { - println("Automatic login is enabled for the liveuser account.", 0x07); - } - - println("", 0x07); - - welcome_msg_displayed = KTRUE; - } - - static char username[32] = {0}; - print("AurorOS login: ", 0x07); - read_str(username, sizeof(username), KFALSE, 0x07); - - if (username[0] == 0) { - println("", 0x07); - print_error("An username has to be provided."); - println("", 0x07); - goto reauth; - } - - Auth::UserEntry* user = Auth::find_user(username, users, users_count); - - static char passwd[32] = {0}; - print(username, 0x07); - print("@", 0x07); - print(PC_NAME, 0x07); - print(" password: ", 0x07); - - if (user && streql(username, "liveuser") && AUROR_LIVEUSER_AUTOLOGIN == KTRUE) { - println("(automatic login)", 0x07); - } else { - read_str(passwd, sizeof(passwd), KTRUE, 0x07); - if (!user || !streql(passwd, user->password)) { - println("", 0x07); - print_error("Login incorrect"); - println("", 0x07); - goto reauth; - } - } - - println("", 0x07); - - shell_main(theme, user->username, user->user_id); - - println("", 0x07); - - goto reauth; - - return -1; -} diff --git a/src/apps/tinypad/tinypad.cpp b/src/apps/tinypad/tinypad.c similarity index 92% rename from src/apps/tinypad/tinypad.cpp rename to src/apps/tinypad/tinypad.c index 7b23599..d89ae30 100644 --- a/src/apps/tinypad/tinypad.cpp +++ b/src/apps/tinypad/tinypad.c @@ -1,13 +1,11 @@ -#include "fs/fs-emulated.h" -extern "C" { - #include - #include - #include - #include - #include - #include - #include -} +#include +#include +#include +#include +#include +#include +#include +#include #define LINE_LENGTH 80 #define BUFFER_INCREMENT 150 @@ -24,7 +22,7 @@ fs_node* resolve_folder(const char* path) { while ((token = strtok(&ptr, '/')) != NULL) { fs_node* child = fs_resolve(token, current); if (!child) { - return reinterpret_castNULL; + return NULL; } current = child; }