Code for autonomous ground vehicle, Data Bus, 3rd place winner in 2012 Sparkfun AVC.

Dependencies:   Watchdog mbed Schedule SimpleFilter LSM303DLM PinDetect DebounceIn Servo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers shell.c Source File

shell.c

00001 #include <stdio.h>
00002 #include "mbed.h"
00003 #include "stdint.h"
00004 #include "DirHandle.h"
00005 #include "SDHCFileSystem.h"
00006 #include "util.h"
00007 #include "Buttons.h"
00008 
00009 extern SDFileSystem sd;
00010 extern Serial pc;
00011 extern Buttons keypad;
00012 
00013 char cwd[64];
00014 char buf[128];
00015 bool debug=false;
00016 
00017 void shell(void);
00018 void termInput(char *cmd);
00019 void resolveDirectory(char *newpath, char *path);
00020 void splitName(char *path, char *dirname, char *basename);
00021 void ls(char *path);
00022 void cd(char *path);
00023 void pwd(void);
00024 void touch(char *path);
00025 void head(char *path);
00026 void cat(char *path);
00027 void send(char *path);
00028 
00029 void shell() {
00030     FILE *fp;
00031     char newpath[64], *arg, cmd[64], cmdline[64];
00032     bool done=false;
00033 
00034     //Logger.SelectCRCMode(1);
00035     
00036     //pc.printf("Formatting...\n");
00037     //int i = Logger.format(32);
00038     //pc.printf("format result: %d\n", i);
00039 
00040     if ((fp = fopen("/log/message.txt", "w")) != NULL) {
00041         for (int i=0; i < 20; i++)
00042             fprintf(fp, "Hello, World!\n");
00043         fclose(fp);
00044         //pc.printf("created!\n");
00045     } else {
00046         pc.printf("Error creating file\n");
00047     }
00048     pc.printf("\n");
00049     
00050     strcpy(cwd, "/log");
00051 
00052     while (!done) {
00053         termInput(cmdline);
00054         arg = split(cmd, cmdline, 64, ' ');
00055         resolveDirectory(newpath, arg);
00056         
00057         if (keypad.pressed) {
00058             keypad.pressed = false;
00059             break;
00060         }        
00061         
00062         if (debug) pc.printf("cmdline:<%s> cmd:<%s> arg:<%s> newpath:<%s>\n", cmdline, cmd, arg, newpath);
00063         
00064         if (!strcmp(cmd, "ls")) {
00065             ls(newpath);
00066         } else if (!strcmp(cmd, "cd")) {
00067             cd(newpath);
00068         } else if (!strcmp(cmd, "pwd")) {
00069             pwd();
00070         } else if (!strcmp(cmd, "head")) {
00071             head(newpath);
00072         } else if (!strcmp(cmd, "cat")) {
00073             cat(newpath);
00074         } else if (!strcmp(cmd, "send")) {
00075             send(newpath);
00076         } else if (!strcmp(cmd, "mkdir")) {
00077             mkdir(newpath, 1023);
00078         } else if (!strcmp(cmd, "debug")) {
00079             debug = !debug;
00080         } else if (!strcmp(cmd, "touch")) {
00081             touch(newpath);
00082         } else if (!strcmp(cmd, "rm")) {
00083             remove(newpath);
00084         } else if (!strcmp(cmd, "exit")) {
00085             done = true;
00086         } else if (cmd[0] == '\0') {
00087             // ignore
00088         } else {
00089             pc.printf("%s: command not found\n", cmd);
00090         }
00091     }
00092 
00093 /*
00094     pc.printf("Printing splitName()\n");
00095     splitName("/SDCard/testdir", dirname, basename);
00096     pc.printf("%s %s\n", dirname, basename);
00097 
00098     pc.printf("Printing resolveDirectory()\n");
00099     resolveDirectory(newpath, "test");
00100     pc.printf("%s\n", newpath);
00101 */
00102 
00103 //    remove("/SDCard/testdir/TEST.txt");
00104     
00105     /*
00106     int test = rename("/SDCard/message.txt", "/SDCard/message2.txt");
00107     fp = fopen("/SDCard/message.txt", "a");
00108     fprintf(fp, "  Result = %d", test);
00109     fclose(fp);
00110     */
00111 
00112     pc.printf ("exiting shell\n");
00113 
00114     return;
00115 }
00116 
00117 
00118 /** termInput
00119  *
00120  */
00121 void termInput(char *cmd) {
00122     int i=0;
00123     char c;
00124     bool done = false;
00125     
00126     memset(cmd, 0, 64);
00127     
00128     pc.printf("# ", cwd);
00129     do {
00130         cmd[i] = 0;
00131         c = pc.getc();
00132         if (c == '\r') { // if return is hit, we're done, don't add \r to cmd
00133             done = true;
00134         } else if (i < 64-1) {
00135             if (c == 0x7f || c == '\b') { // backspace or delete
00136                 if (i > 0) { // if we're at the beginning, do nothing
00137                     i--;
00138                     pc.printf("\b \b");
00139                 }
00140             } else {
00141                 pc.printf("%c", c);
00142                 cmd[i++] = c;
00143             }
00144         }
00145     } while (!done);
00146     pc.printf("\n");
00147 } 
00148 
00149 /** resolveDirectory
00150  * resolve the directory path provided, given the cwd
00151  */
00152 void resolveDirectory(char *newpath, char *path) {
00153     char dirname[32], basename[16];
00154     
00155     /** absolute path */
00156     if (path[0] == '/') {
00157         strcpy(newpath, path);
00158     }
00159     /** relative path */
00160     else {
00161         strcpy(newpath, cwd);
00162         if (path[0] != 0) {
00163             if (newpath[strlen(newpath)-1] != '/')
00164                 strcat(newpath, "/");
00165             strcat(newpath, path);    
00166         }
00167         /** Resolve .. references */
00168         splitName(newpath, dirname, basename);
00169         if (!strcmp(basename, "..")) {
00170             splitName(dirname, newpath, basename);
00171         }
00172     }
00173 }
00174 
00175 // copy t to s until space is reached
00176 // return location of delimiter+1 in t
00177 // if space not found, return t pointing to end of string
00178 // if s or t null, return null
00179 char *splitCmd(char *s, char *t, int max)
00180 {
00181   int i = 0;
00182   
00183   if (s == 0 || t == 0)
00184     return 0;
00185 
00186   while (*t != 0 && i < max) {
00187     *s++ = *t++;
00188     i++;
00189     if (*t == ' ') {
00190         t++;
00191         break;
00192     }
00193   }
00194   *s = 0;
00195     
00196   return t;
00197 }
00198 
00199 /** splitName
00200  * split the path into a dirname and a 
00201  */
00202 void splitName(char *path, char *dirname, char *basename) {
00203     int sep;
00204     
00205     sep = 0;
00206     if (debug) pc.printf("%d\n", strlen(path));
00207     for (int i=strlen(path)-1; i >= 0; i--) {
00208         if (debug) pc.printf("- %c\n", path[i]);
00209         sep = i;
00210         if (path[i] == '/') break;
00211     }
00212     for (int j=0; j < sep; j++) {
00213         if (debug) pc.printf("> %c\n", path[j]);
00214         dirname[j] = path[j];
00215         dirname[j+1] = 0;
00216     }
00217     for (int k=sep+1; k < strlen(path); k++) {
00218         if (debug) pc.printf("* %c\n", path[k]);
00219         basename[k-(sep+1)] = path[k];
00220         basename[k-sep] = 0;    
00221     }
00222     if (debug) pc.printf("d:<%s> b:<%s>\n", dirname, basename);
00223 }
00224 
00225 /** ls
00226  * lists files in the current working directory, 4 columns
00227  */
00228 void ls(char *path) {
00229     if (debug) pc.printf("%s\n", cwd);
00230     DIR *d;
00231     struct dirent *p;
00232     
00233     int count=0;
00234     if ((d = opendir(path)) != NULL) {
00235         while ((p = readdir(d)) != NULL) {
00236             pc.printf("%12s", p->d_name);
00237             if (count++ >= 3) {
00238                 count = 0;
00239                 pc.printf("\n");
00240             }
00241         }
00242         pc.printf("\n");
00243         if (count < 3)
00244             pc.printf("\n");
00245         closedir(d);
00246     } else {
00247         pc.printf("%s: No such directory\n", path);
00248     }
00249 }
00250 
00251 /** cd
00252  * changes current working directory
00253  */
00254 void cd(char *path) {
00255     strcpy(cwd, path);
00256 }
00257 
00258 /** pwd
00259  * print current working directory
00260  */
00261 void pwd() {
00262     pc.printf("%s\n", cwd);
00263 }
00264 
00265 /** touch
00266  * create an empty file
00267  */
00268 void touch(char *path) {
00269     FILE *fp;
00270     if ((fp = fopen(path, "w")) != NULL) {
00271         fclose(fp);
00272     } else {
00273         pc.printf("%s: No such file\n", path);
00274     }
00275 } 
00276 
00277 /** head
00278  * print the first 10 lines of a file
00279  */
00280 void head(char *path) {
00281     FILE *fp;
00282     char line = 0;
00283     
00284     if ((fp = fopen(path, "r")) != NULL) {
00285         while (!feof(fp) && line++ < 10) {
00286             fgets(buf, 128, fp);
00287             pc.printf("%s", buf);
00288         }
00289         fclose(fp);
00290     } else {
00291         pc.printf("%s: No such file\n", path);
00292     }
00293 }
00294 
00295 /** cat
00296  * display the content of a file
00297  */
00298 void cat(char *path) {
00299     FILE *fp;
00300 
00301     if ((fp = fopen(path, "r")) != NULL) {
00302         while (!feof(fp)) {
00303             if (fgets(buf, 127, fp) != NULL)
00304                 pc.printf("%s", buf);
00305         }
00306         fclose(fp);
00307     } else {
00308         pc.printf("%s: No such file\n", path);
00309     }
00310 }
00311 
00312 /** send
00313  * Simple serial file transfer protocol
00314  * Initiates escape sequence: ^A^B, sends filename, ^C, and then file
00315  * contents followed by ^D
00316  */
00317 void send(char *path) {
00318     FILE *fp;
00319     char dirname[32], basename[16];
00320 
00321     if ((fp = fopen(path, "r")) != NULL) {
00322         splitName(path, dirname, basename);
00323         pc.printf("%c%c%s%c", 1, 2, basename, 3);
00324         while (!feof(fp)) {
00325             if (fgets(buf, 127, fp) != NULL)
00326                 pc.printf("%s", buf);
00327         }
00328         fclose(fp);
00329         pc.printf("%c", 4);
00330     } else {
00331         pc.printf("%s: No such file\n", path);
00332     }
00333 }