Simple embedded shell with runtime pluggable commands.

Dependents:   DataBus2018

Implements a simple unix-like shell for embedded systems with a pluggable command architecture.

Revision:
18:2b5ed529ab37
Parent:
17:0739cb2f1930
Child:
19:bf5f5ea4e762
--- a/SimpleShell.cpp	Wed Dec 19 19:02:17 2018 +0000
+++ b/SimpleShell.cpp	Fri Dec 21 20:02:56 2018 +0000
@@ -15,6 +15,19 @@
 #define TAIL    0x7e
 
 
+char *SimpleShell::canon(char *path) {
+    static char result[MAXBUF];
+    
+    if (path[0] != '/') {
+        strncpy(result, _cwd, MAXBUF);
+        strcat(result, "/");
+    }
+    strcat(result, path);
+    
+    return result;
+}
+
+
 SimpleShell::SimpleShell()
 {
     lookupEnd = 0;
@@ -24,6 +37,7 @@
     attach(callback(this, &SimpleShell::pwd), "pwd");
     attach(callback(this, &SimpleShell::cat), "cat");
     attach(callback(this, &SimpleShell::cd), "cd");
+    attach(callback(this, &SimpleShell::ls), "ls");
 }
 
 
@@ -42,7 +56,7 @@
     if (argc == 2) {
         strncpy(_cwd, argv[1], MAXBUF);
     } else {
-        puts("usage: cd <directory>");
+        puts("usage: cd directory");
     }
     return;
 }
@@ -55,6 +69,44 @@
 }
 
 
+void SimpleShell::ls(int argc, char **argv)
+{
+    DIR *d;
+    struct dirent *p;
+    char *path;
+
+    if (argc == 1) {
+        path = _cwd;
+    } else if (argc == 2) {
+        path = argv[1];
+    } else {
+        puts("usage: ls [directory]");
+        return;
+    }
+    
+    int cols=0;
+    if ((d = opendir(path)) != NULL) {
+        while ((p = readdir(d)) != NULL) {
+            if (p->d_name && p->d_name[0] != 0xff) {
+                if (cols++ > 3) {
+                    putc('\n', stdout);
+                    cols = 0;
+                }
+                printf("%-15s  ", p->d_name);
+            }
+        }
+        putc('\n', stdout);
+        if (cols < 3)
+            putc('\n', stdout);
+        closedir(d);
+    } else {
+        puts(path);
+        puts(": No such directory\n");
+    }
+
+    return;
+}
+
 void SimpleShell::cat(int argc, char **argv)
 {
     FILE *fp;
@@ -63,7 +115,7 @@
     
     for (int i=1; i < argc; i++) {
         //resolveDirectory(path, arg);
-        if ((fp = fopen(argv[i], "r")) != NULL) {
+        if ((fp = fopen(canon(argv[i]), "r")) != NULL) {
             while (!feof(fp)) {
                 fgets(buf, MAXBUF-1, fp);
                 fputs(buf, stdout);
@@ -89,7 +141,7 @@
     std::string x;
     
     // Set current working directory
-    strncpy(_cwd, "/log", MAXBUF);
+    strncpy(_cwd, "/etc", MAXBUF);
 
     printf("Type help for assistance.\n");
     help(0, NULL);