mirror of
https://github.com/JannisHeydemann/BoredOS.git
synced 2026-05-30 02:16:58 +00:00
FEATURE: add Bsh + userspace terminal, remove legacy cmd/cli utils
This commit is contained in:
1449
src/userland/cli/bsh.c
Normal file
1449
src/userland/cli/bsh.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,32 +0,0 @@
|
||||
// Copyright (c) 2023-2026 Chris (boreddevnl)
|
||||
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
|
||||
// This header needs to maintain in any file it is present in, as per the GPL license terms.
|
||||
#include <stdlib.h>
|
||||
#include <syscall.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
uint32_t error_color = (uint32_t)sys_get_shell_config("error_color");
|
||||
uint32_t default_color = (uint32_t)sys_get_shell_config("default_text_color");
|
||||
|
||||
if (argc < 2) {
|
||||
printf("Usage: cat <filename>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int fd = sys_open(argv[1], "r");
|
||||
if (fd < 0) {
|
||||
sys_set_text_color(error_color);
|
||||
printf("Error: Cannot open %s\n", argv[1]);
|
||||
sys_set_text_color(default_color);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char buffer[4096];
|
||||
int bytes;
|
||||
while ((bytes = sys_read(fd, buffer, sizeof(buffer))) > 0) {
|
||||
sys_write(1, buffer, bytes);
|
||||
}
|
||||
|
||||
sys_close(fd);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,166 +0,0 @@
|
||||
// Copyright (c) 2023-2026 Chris (boreddevnl)
|
||||
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
|
||||
// This header needs to maintain in any file it is present in, as per the GPL license terms.
|
||||
#include <stdlib.h>
|
||||
#include <syscall.h>
|
||||
|
||||
typedef int bool;
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
void combine_path(char *dest, const char *path1, const char *path2) {
|
||||
int i = 0;
|
||||
while (path1[i]) {
|
||||
dest[i] = path1[i];
|
||||
i++;
|
||||
}
|
||||
if (i > 0 && dest[i-1] != '/') {
|
||||
dest[i++] = '/';
|
||||
}
|
||||
int j = 0;
|
||||
while (path2[j]) {
|
||||
dest[i++] = path2[j++];
|
||||
}
|
||||
dest[i] = 0;
|
||||
}
|
||||
|
||||
const char* get_basename(const char *path) {
|
||||
const char *last_slash = NULL;
|
||||
int len = 0;
|
||||
while (path[len]) {
|
||||
if (path[len] == '/') last_slash = path + len;
|
||||
len++;
|
||||
}
|
||||
|
||||
if (!last_slash) return path;
|
||||
|
||||
// If it ends with a slash, skip it and find the previous one
|
||||
if (last_slash[1] == '\0') {
|
||||
if (len <= 1) return path; // root "/"
|
||||
int i = len - 2;
|
||||
while (i >= 0 && path[i] != '/') i--;
|
||||
if (i < 0) return path;
|
||||
return path + i + 1;
|
||||
}
|
||||
|
||||
return last_slash + 1;
|
||||
}
|
||||
|
||||
void copy_recursive(const char *src, const char *dst) {
|
||||
FAT32_FileInfo info;
|
||||
if (sys_get_file_info(src, &info) < 0) {
|
||||
printf("Error: Cannot get info for %s\n", src);
|
||||
return;
|
||||
}
|
||||
|
||||
if (info.is_directory) {
|
||||
if (sys_mkdir(dst) < 0) {
|
||||
// Might already exist
|
||||
}
|
||||
|
||||
FAT32_FileInfo entries[64];
|
||||
int count = sys_list(src, entries, 64);
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (strcmp(entries[i].name, ".") == 0 || strcmp(entries[i].name, "..") == 0) continue;
|
||||
|
||||
char sub_src[512], sub_dst[512];
|
||||
combine_path(sub_src, src, entries[i].name);
|
||||
combine_path(sub_dst, dst, entries[i].name);
|
||||
copy_recursive(sub_src, sub_dst);
|
||||
}
|
||||
} else {
|
||||
int fd_in = sys_open(src, "r");
|
||||
if (fd_in < 0) {
|
||||
printf("Error: Cannot open source %s\n", src);
|
||||
return;
|
||||
}
|
||||
int fd_out = sys_open(dst, "w");
|
||||
if (fd_out < 0) {
|
||||
printf("Error: Cannot create destination %s\n", dst);
|
||||
sys_close(fd_in);
|
||||
return;
|
||||
}
|
||||
char buffer[4096];
|
||||
int bytes;
|
||||
while ((bytes = sys_read(fd_in, buffer, sizeof(buffer))) > 0) {
|
||||
sys_write_fs(fd_out, buffer, bytes);
|
||||
}
|
||||
sys_close(fd_in);
|
||||
sys_close(fd_out);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
bool recursive = false;
|
||||
char *src_path = NULL;
|
||||
char *dst_path = NULL;
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "-r") == 0) {
|
||||
recursive = true;
|
||||
} else if (!src_path) {
|
||||
src_path = argv[i];
|
||||
} else if (!dst_path) {
|
||||
dst_path = argv[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (!src_path || !dst_path) {
|
||||
printf("Usage: cp [-r] <source> <dest>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
FAT32_FileInfo info_src;
|
||||
if (sys_get_file_info(src_path, &info_src) < 0) {
|
||||
printf("Error: Source %s does not exist\n", src_path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (info_src.is_directory && !recursive) {
|
||||
printf("Error: %s is a directory (use -r to copy recursively)\n", src_path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char actual_dst[512];
|
||||
FAT32_FileInfo info_dst;
|
||||
if (sys_get_file_info(dst_path, &info_dst) == 0 && info_dst.is_directory) {
|
||||
// If destination is a directory, copy INTO it
|
||||
const char *base = get_basename(src_path);
|
||||
// Clean up trailing slash from basename if any (get_basename handles it mostly)
|
||||
char clean_base[256];
|
||||
int k = 0;
|
||||
while (base[k] && base[k] != '/') {
|
||||
clean_base[k] = base[k];
|
||||
k++;
|
||||
}
|
||||
clean_base[k] = 0;
|
||||
combine_path(actual_dst, dst_path, clean_base);
|
||||
} else {
|
||||
strcpy(actual_dst, dst_path);
|
||||
}
|
||||
|
||||
if (recursive) {
|
||||
copy_recursive(src_path, actual_dst);
|
||||
} else {
|
||||
int fd_in = sys_open(src_path, "r");
|
||||
if (fd_in < 0) {
|
||||
printf("Error: Cannot open source %s\n", src_path);
|
||||
return 1;
|
||||
}
|
||||
int fd_out = sys_open(actual_dst, "w");
|
||||
if (fd_out < 0) {
|
||||
printf("Error: Cannot create destination %s\n", actual_dst);
|
||||
sys_close(fd_in);
|
||||
return 1;
|
||||
}
|
||||
char buffer[4096];
|
||||
int bytes;
|
||||
while ((bytes = sys_read(fd_in, buffer, sizeof(buffer))) > 0) {
|
||||
sys_write_fs(fd_out, buffer, bytes);
|
||||
}
|
||||
sys_close(fd_in);
|
||||
sys_close(fd_out);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
// Copyright (c) 2023-2026 Chris (boreddevnl)
|
||||
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
|
||||
// This header needs to maintain in any file it is present in, as per the GPL license terms.
|
||||
#include <stdlib.h>
|
||||
#include <syscall.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
uint64_t dir_color = sys_get_shell_config("dir_color");
|
||||
uint64_t file_color = sys_get_shell_config("file_color");
|
||||
uint64_t size_color = sys_get_shell_config("size_color");
|
||||
uint64_t error_color = sys_get_shell_config("error_color");
|
||||
uint64_t default_color = sys_get_shell_config("default_text_color");
|
||||
|
||||
char path[256];
|
||||
if (argc > 1) {
|
||||
strcpy(path, argv[1]);
|
||||
} else {
|
||||
if (!sys_getcwd(path, sizeof(path))) {
|
||||
strcpy(path, "/");
|
||||
}
|
||||
}
|
||||
|
||||
FAT32_FileInfo info;
|
||||
if (sys_get_file_info(path, &info) < 0) {
|
||||
sys_set_text_color(error_color);
|
||||
printf("Error: Path '%s' does not exist\n", path);
|
||||
sys_set_text_color(default_color);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!info.is_directory) {
|
||||
sys_set_text_color(file_color);
|
||||
printf("[FILE] %s", info.name);
|
||||
sys_set_text_color(size_color);
|
||||
printf(" (%d bytes)\n", info.size);
|
||||
sys_set_text_color(default_color);
|
||||
printf("\nTotal: 1 items\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
FAT32_FileInfo entries[128];
|
||||
int count = sys_list(path, entries, 128);
|
||||
|
||||
if (count < 0) {
|
||||
sys_set_text_color(error_color);
|
||||
printf("Error: Cannot list directory %s\n", path);
|
||||
sys_set_text_color(default_color);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (entries[i].is_directory) {
|
||||
sys_set_text_color(dir_color);
|
||||
printf("[DIR] %s\n", entries[i].name);
|
||||
} else {
|
||||
sys_set_text_color(file_color);
|
||||
printf("[FILE] %s", entries[i].name);
|
||||
sys_set_text_color(size_color);
|
||||
printf(" (%d bytes)\n", entries[i].size);
|
||||
}
|
||||
}
|
||||
|
||||
sys_set_text_color(default_color);
|
||||
printf("\nTotal: %d items\n", count);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
// Copyright (c) 2023-2026 Chris (boreddevnl)
|
||||
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
|
||||
// This header needs to maintain in any file it is present in, as per the GPL license terms.
|
||||
#include <stdlib.h>
|
||||
#include <syscall.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
uint32_t error_color = (uint32_t)sys_get_shell_config("error_color");
|
||||
uint32_t success_color = (uint32_t)sys_get_shell_config("success_color");
|
||||
uint32_t default_color = (uint32_t)sys_get_shell_config("default_text_color");
|
||||
|
||||
if (argc < 2) {
|
||||
printf("Usage: mkdir <dirname>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (sys_mkdir(argv[1]) == 0) {
|
||||
sys_set_text_color(success_color);
|
||||
printf("Created directory: %s\n", argv[1]);
|
||||
} else {
|
||||
sys_set_text_color(error_color);
|
||||
printf("Error: Cannot create directory %s\n", argv[1]);
|
||||
sys_set_text_color(default_color);
|
||||
return 1;
|
||||
}
|
||||
sys_set_text_color(default_color);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
// Copyright (c) 2023-2026 Chris (boreddevnl)
|
||||
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
|
||||
// This header needs to maintain in any file it is present in, as per the GPL license terms.
|
||||
#include <stdlib.h>
|
||||
#include <syscall.h>
|
||||
|
||||
void combine_path(char *dest, const char *path1, const char *path2) {
|
||||
int i = 0;
|
||||
while (path1[i]) {
|
||||
dest[i] = path1[i];
|
||||
i++;
|
||||
}
|
||||
if (i > 0 && dest[i-1] != '/') {
|
||||
dest[i++] = '/';
|
||||
}
|
||||
int j = 0;
|
||||
while (path2[j]) {
|
||||
dest[i++] = path2[j++];
|
||||
}
|
||||
dest[i] = 0;
|
||||
}
|
||||
|
||||
const char* get_basename(const char *path) {
|
||||
const char *last_slash = NULL;
|
||||
int len = 0;
|
||||
while (path[len]) {
|
||||
if (path[len] == '/') last_slash = path + len;
|
||||
len++;
|
||||
}
|
||||
|
||||
if (!last_slash) return path;
|
||||
|
||||
if (last_slash[1] == '\0') {
|
||||
if (len <= 1) return path;
|
||||
int i = len - 2;
|
||||
while (i >= 0 && path[i] != '/') i--;
|
||||
if (i < 0) return path;
|
||||
return path + i + 1;
|
||||
}
|
||||
|
||||
return last_slash + 1;
|
||||
}
|
||||
|
||||
void copy_recursive(const char *src, const char *dst) {
|
||||
FAT32_FileInfo info;
|
||||
if (sys_get_file_info(src, &info) < 0) return;
|
||||
|
||||
if (info.is_directory) {
|
||||
sys_mkdir(dst);
|
||||
FAT32_FileInfo entries[64];
|
||||
int count = sys_list(src, entries, 64);
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (strcmp(entries[i].name, ".") == 0 || strcmp(entries[i].name, "..") == 0) continue;
|
||||
char sub_src[512], sub_dst[512];
|
||||
combine_path(sub_src, src, entries[i].name);
|
||||
combine_path(sub_dst, dst, entries[i].name);
|
||||
copy_recursive(sub_src, sub_dst);
|
||||
}
|
||||
} else {
|
||||
int fd_in = sys_open(src, "r");
|
||||
if (fd_in < 0) return;
|
||||
int fd_out = sys_open(dst, "w");
|
||||
if (fd_out < 0) { sys_close(fd_in); return; }
|
||||
char buffer[4096];
|
||||
int bytes;
|
||||
while ((bytes = sys_read(fd_in, buffer, sizeof(buffer))) > 0) {
|
||||
sys_write_fs(fd_out, buffer, bytes);
|
||||
}
|
||||
sys_close(fd_in);
|
||||
sys_close(fd_out);
|
||||
}
|
||||
}
|
||||
|
||||
void delete_recursive(const char *path) {
|
||||
FAT32_FileInfo info;
|
||||
if (sys_get_file_info(path, &info) < 0) return;
|
||||
|
||||
if (info.is_directory) {
|
||||
FAT32_FileInfo entries[64];
|
||||
int count = sys_list(path, entries, 64);
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (strcmp(entries[i].name, ".") == 0 || strcmp(entries[i].name, "..") == 0) continue;
|
||||
char sub_path[512];
|
||||
combine_path(sub_path, path, entries[i].name);
|
||||
delete_recursive(sub_path);
|
||||
}
|
||||
sys_delete(path);
|
||||
} else {
|
||||
sys_delete(path);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc < 3) {
|
||||
printf("Usage: mv <source> <dest>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *src_path = argv[1];
|
||||
char *dst_path = argv[2];
|
||||
|
||||
FAT32_FileInfo info_src;
|
||||
if (sys_get_file_info(src_path, &info_src) < 0) {
|
||||
printf("Error: Cannot open source %s\n", src_path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char actual_dst[512];
|
||||
FAT32_FileInfo info_dst;
|
||||
if (sys_get_file_info(dst_path, &info_dst) == 0 && info_dst.is_directory) {
|
||||
const char *base = get_basename(src_path);
|
||||
char clean_base[256];
|
||||
int k = 0;
|
||||
while (base[k] && base[k] != '/') {
|
||||
clean_base[k] = base[k];
|
||||
k++;
|
||||
}
|
||||
clean_base[k] = 0;
|
||||
combine_path(actual_dst, dst_path, clean_base);
|
||||
} else {
|
||||
strcpy(actual_dst, dst_path);
|
||||
}
|
||||
|
||||
copy_recursive(src_path, actual_dst);
|
||||
delete_recursive(src_path);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
// Copyright (c) 2023-2026 Chris (boreddevnl)
|
||||
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
|
||||
// This header needs to maintain in any file it is present in, as per the GPL license terms.
|
||||
#include <stdlib.h>
|
||||
#include <syscall.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
uint32_t error_color = (uint32_t)sys_get_shell_config("error_color");
|
||||
uint32_t success_color = (uint32_t)sys_get_shell_config("success_color");
|
||||
uint32_t default_color = (uint32_t)sys_get_shell_config("default_text_color");
|
||||
|
||||
if (argc < 2) {
|
||||
printf("Usage: rm <path>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Simple rm (no recursive support yet for simplicity, but can be added)
|
||||
if (sys_delete(argv[1]) == 0) {
|
||||
sys_set_text_color(success_color);
|
||||
printf("Deleted: %s\n", argv[1]);
|
||||
} else {
|
||||
sys_set_text_color(error_color);
|
||||
printf("Error: Cannot delete %s\n", argv[1]);
|
||||
sys_set_text_color(default_color);
|
||||
return 1;
|
||||
}
|
||||
sys_set_text_color(default_color);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
// Copyright (c) 2023-2026 Chris (boreddevnl)
|
||||
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
|
||||
// This header needs to maintain in any file it is present in, as per the GPL license terms.
|
||||
#include <stdlib.h>
|
||||
#include <syscall.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc < 2) {
|
||||
printf("Usage: touch <filename>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Check if file already exists
|
||||
if (sys_exists(argv[1])) {
|
||||
// Just return success if it exists (simplification)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fd = sys_open(argv[1], "w");
|
||||
if (fd < 0) {
|
||||
printf("Error: Cannot create %s\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
sys_close(fd);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user