diff --git a/CMakeLists.txt b/CMakeLists.txt index 19ca114..02b58a4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -349,7 +349,7 @@ set(RAMDISK_ROOT_APPS) set(USER_SHELL_COMMAND_APPS help ls cat pwd cd exec pid spawn wait sleep yield - shutdown restart exit clear ansi ansitest memstat fsstat taskstat userstat + shutdown restart exit clear ansi ansitest fastfetch memstat fsstat taskstat userstat shstat stats tty dmesg kbdstat mkdir touch write append cp mv grep rm ) diff --git a/cleonos/c/apps/fastfetch_main.c b/cleonos/c/apps/fastfetch_main.c new file mode 100644 index 0000000..e8d0d26 --- /dev/null +++ b/cleonos/c/apps/fastfetch_main.c @@ -0,0 +1,5 @@ +#include "shell/shell_internal.h" + +int cleonos_app_main(void) { + return ush_command_program_main("fastfetch"); +} diff --git a/cleonos/c/apps/shell/shell_cmd.c b/cleonos/c/apps/shell/shell_cmd.c index 95fb82c..833a668 100644 --- a/cleonos/c/apps/shell/shell_cmd.c +++ b/cleonos/c/apps/shell/shell_cmd.c @@ -134,6 +134,7 @@ static int ush_cmd_help(void) { ush_writeln(" exec|run "); ush_writeln(" clear"); ush_writeln(" ansi / ansitest / color"); + ush_writeln(" fastfetch [--plain]"); ush_writeln(" memstat / fsstat / taskstat / userstat / shstat / stats"); ush_writeln(" tty [index]"); ush_writeln(" dmesg [n]"); @@ -1025,6 +1026,162 @@ static int ush_cmd_ansitest(void) { ush_writeln("ansitest done"); return 1; } +static u64 ush_fastfetch_u64_to_dec(char *out, u64 out_size, u64 value) { + char rev[32]; + u64 digits = 0ULL; + u64 i; + + if (out == (char *)0 || out_size == 0ULL) { + return 0ULL; + } + + if (value == 0ULL) { + if (out_size < 2ULL) { + return 0ULL; + } + out[0] = '0'; + out[1] = '\0'; + return 1ULL; + } + + while (value > 0ULL && digits < (u64)sizeof(rev)) { + rev[digits++] = (char)('0' + (value % 10ULL)); + value /= 10ULL; + } + + if (digits + 1ULL > out_size) { + out[0] = '\0'; + return 0ULL; + } + + for (i = 0ULL; i < digits; i++) { + out[i] = rev[digits - 1ULL - i]; + } + out[digits] = '\0'; + return digits; +} + +static void ush_fastfetch_write_u64_dec(u64 value) { + char text[32]; + + if (ush_fastfetch_u64_to_dec(text, (u64)sizeof(text), value) == 0ULL) { + ush_write("0"); + return; + } + + ush_write(text); +} + +static void ush_fastfetch_write_key(int plain, const char *key) { + ush_write(" "); + if (plain == 0) { + ush_write("\x1B[1;96m"); + } + ush_write(key); + if (plain == 0) { + ush_write("\x1B[0m"); + } + ush_write(": "); +} + +static void ush_fastfetch_print_text(int plain, const char *key, const char *value) { + ush_fastfetch_write_key(plain, key); + ush_writeln(value); +} + +static void ush_fastfetch_print_u64(int plain, const char *key, u64 value) { + ush_fastfetch_write_key(plain, key); + ush_fastfetch_write_u64_dec(value); + ush_write_char('\n'); +} + +static void ush_fastfetch_print_logo(int plain) { + if (plain == 0) { + ush_writeln("\x1B[1;34m ____ _ ___ ____ \x1B[0m"); + ush_writeln("\x1B[1;36m / ___| | ___ ___ _ __ / _ \\/ ___| \x1B[0m"); + ush_writeln("\x1B[1;32m | | | |/ _ \\/ _ \\ '__| | | \\___ \\ \x1B[0m"); + ush_writeln("\x1B[1;33m | |___| | __/ __/ | | |_| |___) |\x1B[0m"); + ush_writeln("\x1B[1;31m \\____|_|\\___|\\___|_| \\___/|____/ \x1B[0m"); + } else { + ush_writeln(" ____ _ ___ ____ "); + ush_writeln(" / ___| | ___ ___ _ __ / _ \\/ ___| "); + ush_writeln(" | | | |/ _ \\/ _ \\ '__| | | \\___ \\ "); + ush_writeln(" | |___| | __/ __/ | | |_| |___) |"); + ush_writeln(" \\____|_|\\___|\\___|_| \\___/|____/ "); + } +} + +static void ush_fastfetch_print_palette(int plain) { + ush_fastfetch_write_key(plain, "Palette"); + + if (plain != 0) { + ush_writeln("ANSI16"); + return; + } + + ush_write("\x1B[40m \x1B[0m\x1B[41m \x1B[0m\x1B[42m \x1B[0m\x1B[43m \x1B[0m"); + ush_write("\x1B[44m \x1B[0m\x1B[45m \x1B[0m\x1B[46m \x1B[0m\x1B[47m \x1B[0m "); + ush_write("\x1B[100m \x1B[0m\x1B[101m \x1B[0m\x1B[102m \x1B[0m\x1B[103m \x1B[0m"); + ush_write("\x1B[104m \x1B[0m\x1B[105m \x1B[0m\x1B[106m \x1B[0m\x1B[107m \x1B[0m"); + ush_write_char('\n'); +} + +static int ush_cmd_fastfetch(const char *arg) { + int plain = 0; + u64 tty_active; + u64 tty_count; + u64 exec_req; + u64 exec_ok; + + if (arg != (const char *)0 && arg[0] != '\0') { + if (ush_streq(arg, "--plain") != 0) { + plain = 1; + } else if (ush_streq(arg, "--help") != 0 || ush_streq(arg, "-h") != 0) { + ush_writeln("usage: fastfetch [--plain]"); + return 1; + } else { + ush_writeln("fastfetch: usage fastfetch [--plain]"); + return 0; + } + } + + tty_active = cleonos_sys_tty_active(); + tty_count = cleonos_sys_tty_count(); + exec_req = cleonos_sys_exec_request_count(); + exec_ok = cleonos_sys_exec_success_count(); + + ush_fastfetch_print_logo(plain); + ush_write_char('\n'); + + ush_fastfetch_print_text(plain, "OS", "CLeonOS x86_64"); + ush_fastfetch_print_text(plain, "Shell", "User Shell (/shell/shell.elf)"); + ush_fastfetch_print_u64(plain, "PID", cleonos_sys_getpid()); + ush_fastfetch_print_u64(plain, "UptimeTicks", cleonos_sys_timer_ticks()); + ush_fastfetch_print_u64(plain, "Tasks", cleonos_sys_task_count()); + ush_fastfetch_print_u64(plain, "Services", cleonos_sys_service_count()); + ush_fastfetch_print_u64(plain, "SvcReady", cleonos_sys_service_ready_count()); + ush_fastfetch_print_u64(plain, "CtxSwitches", cleonos_sys_context_switches()); + ush_fastfetch_print_u64(plain, "KELFApps", cleonos_sys_kelf_count()); + ush_fastfetch_print_u64(plain, "KELFRuns", cleonos_sys_kelf_runs()); + ush_fastfetch_print_u64(plain, "FSNodes", cleonos_sys_fs_node_count()); + ush_fastfetch_print_u64(plain, "RootChildren", cleonos_sys_fs_child_count("/")); + + ush_fastfetch_write_key(plain, "TTY"); + ush_fastfetch_write_u64_dec(tty_active); + ush_write(" / "); + ush_fastfetch_write_u64_dec(tty_count); + ush_write_char('\n'); + + ush_fastfetch_write_key(plain, "ExecSuccess"); + ush_fastfetch_write_u64_dec(exec_ok); + ush_write(" / "); + ush_fastfetch_write_u64_dec(exec_req); + ush_write_char('\n'); + + ush_fastfetch_print_u64(plain, "KbdBuffered", cleonos_sys_kbd_buffered()); + ush_fastfetch_print_palette(plain); + return 1; +} static int ush_cmd_kbdstat(void) { ush_writeln("kbdstat:"); ush_print_kv_hex(" BUFFERED", cleonos_sys_kbd_buffered()); @@ -1524,6 +1681,8 @@ static int ush_execute_single_command(ush_state *sh, success = ush_cmd_ansi(); } else if (ush_streq(cmd, "ansitest") != 0) { success = ush_cmd_ansitest(); + } else if (ush_streq(cmd, "fastfetch") != 0) { + success = ush_cmd_fastfetch(arg); } else if (ush_streq(cmd, "memstat") != 0) { success = ush_cmd_memstat(); } else if (ush_streq(cmd, "fsstat") != 0) {