/ firmware / src / programs / shell / shell.cpp
shell.cpp
  1  #include "shell.h"
  2  #include "commands.h"
  3  #include "microfetch.h"
  4  #include "console/path.h"
  5  #include "console/prompt.h"
  6  #include <identity.h>
  7  #include <storage.h>
  8  #include "../coreutils/coreutils.h"
  9  #include "../ssh/ssh_client.h"
 10  #include "../ssh/ssh_server.h"
 11  #include <sqlite.h>
 12  
 13  #include <Arduino.h>
 14  #include <Console.h>
 15  #include <SD.h>
 16  
 17  //------------------------------------------
 18  //  Serial shell state
 19  //------------------------------------------
 20  char g_cwd[128] = "/";
 21  
 22  static void update_prompt() {
 23    Console.setPrompt(console::prompt::build(g_cwd));
 24  }
 25  
 26  static int cmd_resize(int argc, char **argv) {
 27    (void)argc; (void)argv;
 28    console::prompt::detect_width();
 29    update_prompt();
 30    return 0;
 31  }
 32  
 33  static int cmd_cd(int argc, char **argv) {
 34    char prev[128];
 35    strlcpy(prev, g_cwd, sizeof(prev));
 36  
 37    if (argc == 1)
 38      strlcpy(g_cwd, console::path::home_dir(), sizeof(g_cwd));
 39    else
 40      console::path::apply_cd(g_cwd, sizeof(g_cwd), argv[1]);
 41  
 42    if (!SD.exists(g_cwd)) {
 43      strlcpy(g_cwd, prev, sizeof(g_cwd));
 44      printf("no such directory\n");
 45      return 1;
 46    }
 47  
 48    update_prompt();
 49    return 0;
 50  }
 51  
 52  static int cmd_pwd(int argc, char **argv) {
 53    (void)argc; (void)argv;
 54    printf("%s\n", g_cwd);
 55    return 0;
 56  }
 57  
 58  static int cmd_clear(int argc, char **argv) {
 59    (void)argc; (void)argv;
 60    printf("\x1b[2J\x1b[H");
 61    return 0;
 62  }
 63  
 64  void programs::shell::initialize() {
 65    services::identity::initialize();
 66  
 67    Console.setMaxHistory(32);
 68    if (!Console.begin()) {
 69      Serial.println(F("[console] init failed"));
 70      return;
 71    }
 72  
 73    programs::shell::commands::registerAll();
 74    programs::coreutils::registerAll();
 75    programs::shell::microfetch::registerCmd();
 76    Console.addCmd("cd",     "change directory",        "[dir]", cmd_cd);
 77    Console.addCmd("pwd",    "print working directory",  cmd_pwd);
 78    Console.addCmd("clear",  "clear the screen",         cmd_clear);
 79    Console.addCmd("resize", "detect terminal width",    cmd_resize);
 80    programs::ssh_client::registerCommands();
 81    programs::ssh_fingerprint::registerCmd();
 82    programs::sqlite::registerCmd();
 83    Console.addHelpCmd();
 84  
 85    printf("%s", console::prompt::build_motd());
 86    printf("%s", programs::shell::microfetch::generate());
 87    fflush(stdout);
 88  
 89    console::prompt::detect_width();
 90    strlcpy(g_cwd, console::path::home_dir(), sizeof(g_cwd));
 91    update_prompt();
 92  
 93    Console.attachToSerial(true);
 94  }
 95  
 96  void programs::shell::service() {
 97  }
 98  
 99  #ifdef PIO_UNIT_TESTING
100  
101  #include <testing/utils.h>
102  
103  static void test_shell_initializes(void) {
104    WHEN("the console is initialized");
105    programs::shell::initialize();
106    THEN("it completes without error");
107  }
108  
109  void programs::shell::test(void) {
110    MODULE("Shell");
111    RUN_TEST(test_shell_initializes);
112  }
113  
114  #endif