A UNIX emulation shell to access the underlying SDCard FileSystem through a terminal interface

Dependents:   Waldo_Embed_V2

Information

SDShell does not change the com baudrate. Access is made using the baud as initialized by the Serial object when passed into the SDShell object

Example

#include "mbed.h"
#include "SDFileSystem.h"
#include "SDShell.h"

Serial com(USBTX, USBRX);
SDFileSystem sd(p11, p12, p13, p14, "sd");
SDShell emulate;

int main()
{
    emulate.init();
    emulate.shell(com, sd, "/sd");
}

SDShell.cpp

Committer:
sam_grove
Date:
2013-04-26
Revision:
0:618e98bf18ce
Child:
1:514f321aa528

File content as of revision 0:618e98bf18ce:


#include "SDShell.h"

SDShell::SDShell()
{
    return;
}

void SDShell::init(void)
{
    _cmds.attachMsg("ls "    , this, &SDShell::ls);
    _cmds.attachMsg("cd "    , this, &SDShell::cd);
    _cmds.attachMsg("pwd "   , this, &SDShell::pwd);
    _cmds.attachMsg("head "  , this, &SDShell::head);
    _cmds.attachMsg("cat "   , this, &SDShell::cat);
    _cmds.attachMsg("mkdir " , this, &SDShell::mkdir);
//    _cmds.attachMsg("debug" , this, &SDShell::LOG_Handler);
    _cmds.attachMsg("touch " , this, &SDShell::touch);
    _cmds.attachMsg("rm "    , this, &SDShell::remove);
//    _cmds.attachMsg("exit"  , this, &SDShell::LOG_Handler);
    
    return;
}

void SDShell::shell(Serial &com, SDFileSystem &storage, char *cwd)
{
    // should check on the device here
    _com = &com;
    strcpy(_cwd, cwd);
        
    _com->printf("%s \n", _cwd);   // print out the directory that we're in
    while(1)
    {
        char c = _com->getc();
        if (c == '\r')      // look for something to do
        {
            _cmds.serviceMessage(_rxbuf.data);
            _com->printf("\nECHO: %s \n", _rxbuf.data);
            
            memset(_rxbuf.data, 0, _rxbuf.loc-1);
            _rxbuf.loc = 0;            
        }
        else if (c == 0x7f) // backspace
        {
            if (_rxbuf.loc > 0)
            {
                _rxbuf.loc--;
                _com->printf("\b \b");
            }
        }
        else
        {
            _com->putc(c);
            _rxbuf.data[_rxbuf.loc++] = c;
            _rxbuf.loc &= SHELL_RXBUF_MASK;
        }
    }
    return;
} 

// not working - need to pick back up here
char *SDShell::ls(char *string)
{
    //ls: lists files in the current working directory
    _com->printf(" %s\n", _cwd);
    
    DIR *d = opendir(_cwd); // <- problem here??
    _com->printf(" %s\n", _cwd);
    if(d != NULL) 
    {
        struct dirent *p;
        _com->printf(" %s\n", _cwd);
        do 
        {
            p = readdir(d);   // doesn't take parameter?? where does this go?
            _com->printf(" file: %s\n", p->d_name);
        }
        while(p != NULL);
        
        closedir(d);
    }
    else
    {
        _com->printf("%s: No such directory\n", _cwd);
    }
    
    return string;
}

char *SDShell::cd(char *string){ return string;}
char *SDShell::pwd(char *string){ return string;}
char *SDShell::head(char *string){ return string;}

char *SDShell::cat(char *string)
{
    // display the content of a file eg: cat readme.txt
    resolvePath((string+4));
        
    FILE *fp = fopen(_path_to_file, "r");    
    if(NULL != fp)
    {
        char *buf = new char [1024];
        while (!feof(fp))
        {
            fgets(buf, sizeof(buf), fp);
            _com->printf("%s", buf);
        }
        fclose(fp);
        delete [] buf;
    } 
    else
    {
        _com->printf("\n%s: No such file\n", _path_to_file);
    }
    
    return string;
 }

char *SDShell::mkdir(char *string){ return string;}
char *SDShell::touch(char *string){ return string;}
char *SDShell::remove(char *string){ return string;}

char *SDShell::resolvePath(char *string)
{
    strcpy(_path_to_file, _cwd);
    strcat(_path_to_file, "/");
    strcat(_path_to_file, string);
    
    return _path_to_file;
}



//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;
//}
// 
// 
///** 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);
//    }
//}