←

Useless Shell

Icon for Useless Shell. GitHub Repo

A shell written in C with no purpose. However, it was fun to write.

Welcome, Guest.                         
                            
Today is Fri Oct 11 09:54:10 2024.      
> help                                  
- exit                                  
- help (cmd) -b                         
- clear                                 
- history                               
  Display the session command history   
  - clear                               
- login <username>                      
  Login to an existing account          
- logout                                
  Logout of the currect account         
- users                                 
  - info (username)                     
  - list                                
  - create <username> <password> (super)
  - delete <username>                   
- uninstall                             
- time -d -w                            
  Shows system time                     
> users list                            
1       [@] admin                       
> time -d                               
 _   _     __  __   __  _               
| | |_| ' |_  |_  '  _|  |              
|_| __| . __| __| . |__ _|_             
>

Features

Installation

Download the latest release or build from source with CMake.

Note that a config directory is placed at:

(Linux)~/.config/useless_shell
(Windows)~/AppData/Roaming/.useless-shell

Run the executable and enter a password for the new admin user.

Adding a new command

  1. Add definition to cmd_defs.c

    Use the CMD macro with named-member-initalization style for name, description, type, optional, impl, and auto_complete.
    name and type are required, while the others are optional.

    Valid types must be prefixed with USCommandArgType and are as follows:
    Number, String, Secret, Boolean, and Flag.

    When type is Flag, optional and auto_complete are ignored.

    impl describes the implementation. Set it to the CMD_IMPL macro

    Example
    CMD(
        .name = "history",
        .description = "Display the session command history",
        .impl = CMD_IMPL(history),
        SUB_CMDS(
            CMD(
                .name = "clear",
                .impl = CMD_IMPL(history_clear)
            )
        )
    )
  2. Add implementation declaration to cmd_impl.h

    Call the CMD_IMPL_PROTO with the implementation name you chose in the previous step.

    Example
    CMD_IMPL_PROTO(history);
  3. Add implementation to cmd_impl.c

    Example
    CMD_IMPL_PROTO(history)
    {
        // Information about the shell can be accessed via `us` parameter
        if (fseek(us->history.read, 0, SEEK_SET) == 0)
        {
            ...
        }
        else
        {
            puts(STYLE_ERROR("Failed to read history"));
            return USCommandReturnError;
        }
        return USCommandReturnNormal;
    }

Adding a new auto complete function is very similar, but uses the AC_IMPL and AC_IMPL_PROTO macros instead.