Demonstration of a very simple unix-like shell. Based on integrating both Klaus Bu\'s SDHCFileSystem and the FATFileSystem library out of Thomas Hamilton\'s SDCard program. Result: you get high capacity + a plethora of filesystem functions.

Dependencies:   mbed

Revision:
0:792bddcf799d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Oct 11 15:13:42 2011 +0000
@@ -0,0 +1,315 @@
+#include "mbed.h"
+#include "stdint.h"
+#include "DirHandle.h"
+#include "SDHCFileSystem.h"
+
+SDFileSystem sd(p5, p6, p7, p8, "SDCard"); // mosi, miso, sclk, cs
+
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+DigitalOut led4(LED4);
+Serial pc(USBTX, USBRX);
+
+// cd
+// cat
+// ls
+
+char cwd[64];
+char arg[64];
+char buf[128];
+bool debug=false;
+
+void shell(void);
+char *split(char *s, char *t, int max, char delim);
+void termInput(char *cmd);
+void resolveDirectory(char *newpath, char *path);
+void splitName(char *path, char *dirname, char *basename);
+void ls(char *path);
+void cd(char *path);
+void pwd(void);
+void touch(char *path);
+void head(char *path);
+void cat(char *path);
+
+int main()
+{
+    pc.baud(115200);
+    
+    shell();
+    
+    while (1) {
+        led1 = !led1;
+        wait_ms(250);
+        led2 = !led2;
+        wait_ms(250);
+        led3 = !led3;
+        wait_ms(250);
+        led4 = !led4;
+        wait_ms(250);
+    }
+}
+
+void shell() {
+    FILE *fp;
+    char newpath[64], *arg, cmd[64], cmdline[64];
+    bool done=false;
+
+    //Logger.SelectCRCMode(1);
+    
+    //pc.printf("Formatting...\n");
+    //int i = Logger.format(32);
+    //pc.printf("format result: %d\n", i);
+
+    if ((fp = fopen("/SDCard/message.txt", "w")) != NULL) {
+        for (int i=0; i < 20; i++)
+            fprintf(fp, "Hello, World!\n");
+        fclose(fp);
+        //pc.printf("created!\n");
+    } else {
+        pc.printf("Error creating file\n");
+    }
+    pc.printf("\n");
+    
+    strcpy(cwd, "/SDCard");
+
+    while (!done) {
+        termInput(cmdline);
+        arg = split(cmd, cmdline, 64, ' ');
+        resolveDirectory(newpath, arg);
+        
+        if (debug) pc.printf("cmdline:<%s> cmd:<%s> arg:<%s> newpath:<%s>\n", cmdline, cmd, arg, newpath);
+        
+        if (!strcmp(cmd, "ls")) {
+            ls(newpath);
+        } else if (!strcmp(cmd, "cd")) {
+            cd(newpath);
+        } else if (!strcmp(cmd, "pwd")) {
+            pwd();
+        } else if (!strcmp(cmd, "head")) {
+            head(newpath);
+        } else if (!strcmp(cmd, "cat")) {
+            cat(newpath);
+        } else if (!strcmp(cmd, "mkdir")) {
+            mkdir(newpath, 1023);
+        } else if (!strcmp(cmd, "debug")) {
+            debug = !debug;
+        } else if (!strcmp(cmd, "touch")) {
+            touch(newpath);
+        } else if (!strcmp(cmd, "rm")) {
+            remove(newpath);
+        } else if (!strcmp(cmd, "exit")) {
+            done = true;
+        } else {
+            pc.printf("%s: command not found\n", cmd);
+        }
+    }
+
+/*
+    pc.printf("Printing splitName()\n");
+    splitName("/SDCard/testdir", dirname, basename);
+    pc.printf("%s %s\n", dirname, basename);
+
+    pc.printf("Printing resolveDirectory()\n");
+    resolveDirectory(newpath, "test");
+    pc.printf("%s\n", newpath);
+*/
+
+//    remove("/SDCard/testdir/TEST.txt");
+    
+    /*int test = rename("/SDCard/message.txt", "/SDCard/message2.txt");
+    fp = fopen("/SDCard/message.txt", "a");
+    fprintf(fp, "  Result = %d", test);
+    fclose(fp);*/
+
+    pc.printf ("exiting shell\n");
+
+    return;
+}
+
+// copy t to s until delimiter is reached
+// return location of delimiter+1 in t
+char *split(char *s, char *t, int max, char delim)
+{
+  int i = 0;
+  char *v;
+  
+  if (s == 0 || t == 0)
+    return 0;
+
+  while (*t != 0 && *t != delim && i < max) {
+    *s++ = *t++;
+    i++;
+  }
+  *s = 0;
+  
+  if (*t == '\0')
+    v = s;
+  else
+    v = t+1;
+    
+  return v;
+}
+
+
+/** termInput
+ *
+ */
+void termInput(char *cmd) {
+    int i=0;
+    char c;
+    bool done = false;
+    
+    memset(cmd, 0, 64);
+    
+    pc.printf("# ", cwd);
+    do {
+        cmd[i] = 0;
+        c = pc.getc();
+        if (c == '\r') { // if return is hit, we're done, don't add \r to cmd
+            done = true;
+        } else if (i < 64-1) {
+            if (c == 0x7f) { // backspace
+                if (i > 0) { // if we're at the beginning, do nothing
+                    i--;
+                    pc.printf("\b \b");
+                }
+            } else {
+                pc.printf("%c", c);
+                cmd[i++] = c;
+            }
+        }
+    } while (!done);
+    pc.printf("\n");
+} 
+
+/** resolveDirectory
+ * resolve the directory path provided, given the cwd
+ */
+void resolveDirectory(char *newpath, char *path) {
+    char basename[64], dirname[64];
+    
+    /** absolute path */
+    if (path[0] == '/') {
+        strcpy(newpath, path);
+    }
+    /** relative path */
+    else {
+        strcpy(newpath, cwd);
+        if (path[0] != 0) {
+            if (newpath[strlen(newpath)-1] != '/')
+                strcat(newpath, "/");
+            strcat(newpath, path);    
+        }
+        /** Resolve .. references */
+        splitName(newpath, dirname, basename);
+        if (!strcmp(basename, "..")) {
+            splitName(dirname, newpath, basename);
+        }
+    }
+}
+
+/** splitName
+ * split the path into a dirname and a basename
+ */
+void splitName(char *path, char *dirname, char *basename) {
+    int sep;
+    
+    sep = 0;
+    if (debug) pc.printf("%d\n", strlen(path));
+    for (int i=strlen(path)-1; i >= 0; i--) {
+        if (debug) pc.printf("- %c\n", path[i]);
+        sep = i;
+        if (path[i] == '/') break;
+    }
+    for (int j=0; j < sep; j++) {
+        if (debug) pc.printf("> %c\n", path[j]);
+        dirname[j] = path[j];
+        dirname[j+1] = 0;
+    }
+    for (int k=sep+1; k < strlen(path); k++) {
+        if (debug) pc.printf("* %c\n", path[k]);
+        basename[k-(sep+1)] = path[k];
+        basename[k-sep] = 0;    
+    }
+    if (debug) pc.printf("d:<%s> b:<%s>\n", dirname, basename);
+}
+
+/** ls
+ * lists files in the current working directory
+ */
+void ls(char *path) {
+    if (debug) pc.printf("%s\n", cwd);
+    DIR *d;
+    struct dirent *p;
+    
+    if ((d = opendir(path)) != NULL) {
+        while ((p = readdir(d)) != NULL) {
+              pc.printf(" %s\n", p->d_name);
+        }
+        closedir(d);
+    } else {
+        pc.printf("%s: No such directory\n", path);
+    }
+}
+
+/** cd
+ * changes current working directory
+ */
+void cd(char *path) {
+    strcpy(cwd, path);
+}
+
+/** pwd
+ * print current working directory
+ */
+void pwd() {
+    pc.printf("%s\n", cwd);
+}
+
+/** touch
+ * create an empty file
+ */
+void touch(char *path) {
+    FILE *fp;
+    if ((fp = fopen(path, "w")) != NULL) {
+        fclose(fp);
+    } else {
+        pc.printf("%s: No such file\n", path);
+    }
+} 
+
+/** head
+ * print the first 10 lines of a file
+ */
+void head(char *path) {
+    FILE *fp;
+    char line = 0;
+    
+    if ((fp = fopen(path, "r")) != NULL) {
+        while (!feof(fp) && line++ < 10) {
+            fgets(buf, 128, fp);
+            pc.printf("%s", buf);
+        }
+        fclose(fp);
+    } else {
+        pc.printf("%s: No such file\n", path);
+    }
+}
+
+/** cat
+ * display the content of a file
+ */
+void cat(char *path) {
+    FILE *fp;
+
+    if ((fp = fopen(path, "r")) != NULL) {
+        while (!feof(fp)) {
+            fgets(buf, 128, fp);
+            pc.printf("%s", buf);
+        }
+        fclose(fp);
+    } else {
+        pc.printf("%s: No such file\n", path);
+    }
+}