#include "src/lib/memory.h" #include "src/lib/string.h" #include "src/lib/util.h" #include "src/user/syscall.h" static void help(uint8_t argc, char **argv); static void cd(uint8_t argc, char **argv); #define PATH "/bin/" #define PRINT_S(s) write(1, s, sizeof(s) - 1); #define PRINT_D(s) write(1, s, string_length(s)); typedef void (*app_t)(uint8_t argc, char **argv); typedef struct { const char *name; app_t app; } app_entry_t; static app_entry_t builtins[] = { {"help", help}, {"cd", cd}, }; static void help(uint8_t argc, __attribute__((unused)) char **argv) { if (argc > 1) { PRINT_S("help: expects no arguments"); return; } PRINT_S("Available commands:\n"); for (uint64_t i = 0; i < sizeof(builtins) / sizeof(app_entry_t); i++) { PRINT_D(builtins[i].name); PRINT_S("\n"); } } static void cd(uint8_t argc, char **argv) { if (argc != 2) { PRINT_S("cd: requires a single path\n"); return; } if (chdir(argv[1]) == (uint64_t)-1) { PRINT_S("cd: path does not exist\n"); } } static void print_prompt() { char path[256]; uint8_t pl = getcwd(256, path); char *components[16]; uint8_t cl = string_split(path, '/', 16, components); PRINT_S("[") PRINT_D(pl == 1 ? "/" : components[cl - 1]); PRINT_S("]$ "); } static void execute(char *command) { char *argv[16]; uint8_t argc = (uint8_t)string_split(command, ' ', 16, argv); PRINT_S("\n"); if (string_equal(command, "^C")) { print_prompt(); return; } if (string_equal(command, "^D")) { exit(EXIT_CODE_OK); } uint8_t i; for (i = 0; i < sizeof(builtins) / sizeof(app_entry_t); i++) { if (string_equal(argv[0], builtins[i].name)) { builtins[i].app(argc, argv); break; } } if (i == sizeof(builtins) / sizeof(app_entry_t)) { uint64_t size = sizeof(PATH) + string_length(argv[0]) + 1; char *path = memory_allocate(size); memory_copy(PATH, sizeof(PATH), path); memory_copy(argv[0], size - sizeof(PATH), path + sizeof(PATH) - 1); uint64_t pid = spawn(path, argc, (const char **)argv); memory_free(path); if (pid == EXIT_CODE_NOT_FOUND) { PRINT_S("shell: program not found\n"); } else { waitpid(pid); } } print_prompt(); } uint64_t main() { PRINT_D("Welcome to FreywarOS v" VERSION "!\n\n"); print_prompt(); char line[256]; uint64_t offset; char chunk[64]; uint64_t received; while (1) { if ((received = read(0, sizeof(chunk), chunk))) { for (uint64_t i = 0; i < received; i++) { if (chunk[i] == '\n') { line[offset] = '\0'; execute(line); offset = 0; } else if (offset < 255) { line[offset++] = chunk[i]; } } } } return 0; }