This is the firmware for the LaOS - Laser Open Source project. You can use it to drive a laser cutter. For hardware and more information, look at our wiki: http://wiki.laoslaser.org

Dependencies:   EthernetNetIf mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers laosfilesystem.cpp Source File

laosfilesystem.cpp

00001 /*
00002  *
00003  * LaosFilesystem.cpp
00004  * Simple Long Filename system on top of SDFilesystem.h
00005  *
00006  * Copyright (c) 2011 Jaap Vermaas
00007  *
00008  *   This file is part of the LaOS project (see: http://wiki.laoslaser.org
00009  *
00010  *   LaOS is free software: you can redistribute it and/or modify
00011  *   it under the terms of the GNU General Public License as published by
00012  *   the Free Software Foundation, either version 3 of the License, or
00013  *   (at your option) any later version.
00014  *
00015  *   LaOS is distributed in the hope that it will be useful,
00016  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *   GNU General Public License for more details.
00019  *
00020  *   You should have received a copy of the GNU General Public License
00021  *   along with LaOS.  If not, see <http://www.gnu.org/licenses/>.
00022  *
00023  */
00024 #include "laosfilesystem.h"
00025 
00026 LaosFileSystem::LaosFileSystem(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name)
00027         : SDFileSystem(mosi, miso, sclk, cs, name) {
00028     sprintf(tablename, "/%s/%s", name, _LAOSFILE_TRANSTABLE);
00029     sprintf(pathname, "/%s/", name);
00030 }
00031 
00032 LaosFileSystem::~LaosFileSystem() {
00033 }
00034 
00035 FILE* LaosFileSystem::openfile(char *name, char* iom) {
00036     if (islegalname(name)) {  // check length and chars in name
00037 
00038         char shortname[SHORTFILESIZE] = "";
00039         getshortname(shortname, name);
00040         char fullname[MAXFILESIZE+SHORTFILESIZE+1];
00041         if (strstr(iom, "r")) {        // open file for reading
00042             if (strlen(shortname)!=0) {
00043                 sprintf(fullname, "%s%s", pathname, shortname);
00044                 return fopen(fullname, iom);
00045             } else {                // no file exists
00046                 return NULL;
00047             }
00048         } else {                    // open file for writng
00049             if (strlen(shortname)!=0) {
00050                 sprintf(fullname, "%s%s", pathname, shortname);
00051                 return fopen(fullname, iom);
00052             } else {                    // create a new file
00053                 makeshortname(shortname, name);
00054                 sprintf(fullname, "%s%s", pathname, shortname);
00055                 return fopen(fullname, iom);
00056             }
00057         }
00058     } else {    // (islegalname(name))
00059         return NULL;
00060     }
00061 }
00062 
00063 void LaosFileSystem::getlongname(char *result, char *searchname) {
00064     FILE *fp = fopen(tablename, "r");
00065     if (fp) {
00066         char longname[MAXFILESIZE];
00067         char shortname[SHORTFILESIZE];
00068         while (dirread(longname, shortname, fp))
00069             if (! strcmp(shortname, searchname))
00070                 break;
00071         if (strcmp(shortname, searchname))
00072             strcpy(result, searchname);
00073         else
00074             strcpy(result, longname);
00075         fclose(fp);
00076     } else {
00077         strcpy(result, searchname);
00078     }
00079 }
00080 
00081 int LaosFileSystem::islegalname(char* name) {
00082     if (( strlen(name) > MAXFILESIZE-1 ) || (strlen(name) == 0))
00083         return 0;
00084     int legal = 1;
00085     char nochar[] = "?*,;=+#>|[]/\\";
00086     int x = 0;
00087     while (legal && (name[x] != 0)) {
00088         legal *= (name[x] > 32) && (name[x] < 126);
00089         int y = 0;
00090         while (legal && (nochar[y] != 0))
00091             legal *= name[x] != nochar[y++];
00092         x++;
00093     }
00094     return legal;
00095 }
00096 
00097 int LaosFileSystem::isshortname(char* name) {
00098     int len = strlen(name);
00099     for (int x=0; x<len; x++)
00100         if (name[x] == ' ') return 0; // spaces not allowed in shortname
00101 
00102     char myname[MAXFILESIZE];
00103     strcpy(myname, name);
00104     char *basename = NULL;
00105     if (len <= SHORTFILESIZE-1) {
00106         basename = strtok(myname, ".");
00107         if (strlen(basename) > 8) {
00108             return 0;    // basename was too long
00109         } else {
00110             if (char *ext_name = strtok(NULL, ".")) {  //
00111                 if ((strlen(basename)+strlen(ext_name)+1) == len) {
00112                     if (strlen(ext_name)<4) {
00113                         return 1; // filename is in 8.3 format
00114                     } else {
00115                         return 0; // extension too long
00116                     }
00117                 } else {
00118                     return 0; // there was more then one dot
00119                 }
00120             } else {
00121                 return 1; // filename of max 8 chars, no extension (OK)
00122             }
00123         }
00124     } else {
00125         return 0; // total filename too long
00126     }
00127 }
00128 
00129 void LaosFileSystem::removespaces(char* name) {
00130     int spaces = 1;
00131     while (spaces) {
00132         spaces = 0;
00133         int x = 0;
00134         while ((name[x] != ' ') && (x<strlen(name))) x++;
00135         if (name[x] == ' ') {
00136             spaces = 1;
00137             for (int y = x; x<(strlen(name)-1); y++)
00138                 name[y] = name[y+1];
00139         }
00140     }
00141 }
00142 
00143 void LaosFileSystem::getshortname(char* shortname, char* name) {
00144     // * open filename translation table
00145     // * and see if a file with that name exists
00146     if (isshortname(name)) {
00147         strcpy(shortname, name);
00148     } else {
00149         int found = 0;
00150         char longname[MAXFILESIZE];
00151         FILE *fp = fopen(tablename, "r");
00152         if (fp) {
00153             while (dirread(longname, shortname, fp)) {
00154                 if (!strcmp(longname, name)) {
00155                     found = 1;
00156                     break;
00157                 }
00158             }
00159             if (! found) strcpy(shortname, "");
00160             fclose(fp);
00161         }
00162     }
00163 }
00164 
00165 void LaosFileSystem::makeshortname(char* shortname, char* name) {
00166     char *tmpname = new char[MAXFILESIZE];
00167     strcpy(tmpname, name);
00168     removespaces(tmpname);
00169     shorten(tmpname, SHORTFILESIZE);
00170     char *basename = strtok(tmpname, ".");
00171     char *ext_name = strtok(NULL, ".");
00172     strtolower(basename);
00173     strtolower(ext_name);
00174     int cnt = 1;
00175     char fullname[MAXFILESIZE+SHORTFILESIZE+2];
00176     FILE *fp = NULL;
00177     do {
00178         if (fp != NULL) fclose(fp);
00179         while ((cnt/10+strlen(basename)+2) > 8)
00180             basename[strlen(basename)-1] = 0;
00181         if (strlen(ext_name) > 0) {
00182             sprintf(shortname, "%s~%d.%s", basename, cnt++, ext_name);
00183         } else {
00184             sprintf(shortname, "%s~%d", basename, cnt++);
00185         }
00186         sprintf(fullname, "%s%s", pathname, shortname);
00187         fp = fopen(fullname, "rb");
00188     } while (fp!=NULL);
00189     
00190     FILE *tfp = fopen(tablename, "ab");
00191     dirwrite(name, shortname, tfp);
00192     fclose(tfp);
00193 
00194     delete(tmpname);
00195 }
00196 
00197 void LaosFileSystem::cleanlist() {
00198     // * open filename translation table
00199     char longname[MAXFILESIZE];
00200     char shortname[SHORTFILESIZE];
00201     char tabletmpname[MAXFILESIZE+SHORTFILESIZE+1];
00202     strcpy (tabletmpname, tablename);
00203     tabletmpname[strlen(tabletmpname)-1] = '~';
00204     
00205     // make a full copy of the table
00206     FILE* fp1 = fopen(tablename, "rb");
00207     if (fp1 == NULL) return;
00208     FILE* fp2 = fopen(tabletmpname, "wb");
00209     if (fp2 == NULL) return;
00210     while (dirread(longname, shortname, fp1))
00211         dirwrite(longname, shortname, fp2);
00212     fclose(fp1);
00213     fclose(fp2);
00214 
00215     fp1 = fopen(tablename, "wb");
00216     if (fp1 == NULL) return;
00217     fp2 = fopen(tabletmpname, "rb");
00218     if (fp2 == NULL) return;
00219     FILE* fp;
00220     while (dirread(longname, shortname, fp2)) {
00221         char fullname[MAXFILESIZE+SHORTFILESIZE+1];
00222         sprintf(fullname, "%s%s", pathname, shortname);
00223         fp = fopen(fullname, "rb");
00224         if (fp != NULL) {
00225             fclose(fp);
00226             dirwrite(longname, shortname, fp1);
00227         } 
00228      }
00229      fclose(fp1);
00230      fclose(fp2);
00231 }
00232 
00233 void LaosFileSystem::shorten(char* name, int max) {
00234     int len = 0;
00235     while (name[len++] != 0);   /* end of string */
00236     len--;
00237     if (len > max-1) {
00238         int ext = len;
00239         while (name[--ext] != '.'); /* begin of extension */
00240         int baselen, extlen;
00241         baselen = ext;
00242         extlen = len-ext-1;
00243         while ((baselen > max-5) && (baselen+extlen+1 > max-1))
00244             baselen--;
00245         name[baselen++] = '.';
00246         while ((ext<len) && (baselen < max-1))
00247             name[baselen++] = name[++ext];
00248         name[baselen] = 0;
00249     }
00250 }
00251 
00252 size_t LaosFileSystem::dirread(char* longname, char* shortname, FILE *fp) {
00253     char buff[MAXFILESIZE+SHORTFILESIZE];
00254     size_t result = fread(buff, 1, MAXFILESIZE+SHORTFILESIZE, fp);
00255     if (result) {       
00256         strncpy(longname, buff, MAXFILESIZE);
00257         longname[MAXFILESIZE-1] = 0;
00258         int cnt = MAXFILESIZE-2;
00259         while (longname[cnt]==' ') longname[cnt--] = 0;
00260         
00261         strncpy(shortname, &buff[MAXFILESIZE], SHORTFILESIZE);
00262         shortname[SHORTFILESIZE-1] = 0;
00263         cnt = SHORTFILESIZE-2;
00264         while (shortname[cnt]==' ') shortname[cnt--] = 0;
00265     }
00266     return result;
00267 }
00268 
00269 size_t LaosFileSystem::dirwrite(char* longname, char* shortname, FILE* fp) {
00270     char buff[MAXFILESIZE+SHORTFILESIZE];
00271     int x=0; 
00272     while (longname[x] != 0) buff[x++] = longname[x];
00273     while (x<MAXFILESIZE-1) buff[x++] = ' ';
00274     buff[x++] = '\t';
00275     while (shortname[x-MAXFILESIZE] != 0) buff[x++] = shortname[x-MAXFILESIZE];
00276     while (x<MAXFILESIZE+SHORTFILESIZE-1) buff[x++] = ' ';
00277     buff[x++] = '\n';
00278     
00279     return fwrite(buff, 1, MAXFILESIZE+SHORTFILESIZE, fp);
00280 }
00281 
00282 void showfile() {
00283     char buff[35];
00284     FILE *fp = fopen("/sd/longname.sys","rb");
00285     if (fp) {
00286         printf("Contents of longname.sys\n\r");
00287         while (fread(buff, 1, MAXFILESIZE+SHORTFILESIZE, fp))
00288             printf("> %s\r", buff);
00289         fclose(fp);
00290         printf("\n\r");
00291     }
00292 }
00293 
00294 void cleandir() {
00295     DIR *d;
00296     struct dirent *p;
00297     d = opendir("/sd");
00298     if(d != NULL) {
00299         while((p = readdir(d)) != NULL) {
00300             char fullname[MAXFILESIZE+SHORTFILESIZE+2];
00301             sprintf(fullname, "/sd/%s", p->d_name);
00302             remove(fullname);
00303         }
00304     } else {
00305         error("Could not open directory!\n\r");
00306     }
00307 }
00308 
00309 void printdir() {
00310     extern LaosFileSystem sd;
00311     printf("List of files in /sd\n\r");
00312     DIR *d;
00313     struct dirent *p;
00314     d = opendir("/sd");
00315     if(d != NULL) {
00316         // printf("...\n\r");
00317         while((p = readdir(d)) != NULL) {
00318             // printf("Short %s\n\r", p->d_name);
00319             if (strncmp(p->d_name, "longname.sy",11)) {
00320                 char longname[MAXFILESIZE];
00321                 // printf("Getlongname\n\r");
00322                 sd.getlongname(longname, p->d_name);
00323                 printf(" - %s (short: %s)\n\r", longname, p->d_name);
00324             }
00325         }
00326     } else {
00327         printf("Could not open directory!\n\r");
00328     }
00329 }
00330 
00331 void getprevjob(char *name) {
00332     extern LaosFileSystem sd;
00333     char shortname[SHORTFILESIZE], last[SHORTFILESIZE];
00334     strcpy(last, "");
00335     sd.getshortname(shortname, name);
00336     DIR *d;
00337     struct dirent *p;
00338     d = opendir("/sd");
00339     if(d != NULL) {
00340         while((p = readdir(d)) != NULL) {
00341             if (strncmp(p->d_name, "longname.sy",11)) { // skip longname.sy*
00342                 if (! strcmp(shortname, p->d_name)) {   // shortname = current entry
00343                     if (strcmp(last, "")) {
00344                         sd.getlongname(name, last);     // return entry before
00345                     } else {
00346                         sd.getlongname(name, p->d_name);    // last="", so current = first
00347                     }
00348                     closedir(d);
00349                     return;
00350                 }
00351                 strcpy(last, p->d_name);
00352             }
00353         } // while
00354         closedir(d);
00355     } else {
00356         printf("Getfilename: Could not open directory!\n\r");
00357     }
00358     sd.getlongname(name, last); // name not found (return last) 
00359                                 // or no file found (return "") 
00360 }
00361 
00362 void getnextjob(char *name) {
00363     extern LaosFileSystem sd;
00364     char shortname[SHORTFILESIZE], last[SHORTFILESIZE];
00365     strcpy(last, "");
00366     sd.getshortname(shortname, name);
00367     DIR *d;
00368     struct dirent *p;
00369     d = opendir("/sd");
00370     if(d != NULL) {
00371         while((p = readdir(d)) != NULL) {
00372             if (strncmp(p->d_name, "longname.sy",11)) { // skip longname.sy*
00373                 if (! strcmp(shortname, last)) {        // if last was shortname
00374                     sd.getlongname(name, p->d_name);    //    return current
00375                     closedir(d);
00376                     return;
00377                 }
00378                 strcpy(last, p->d_name);
00379             }
00380         } // while
00381         closedir(d);
00382     } else {
00383         printf("Getfilename: Could not open directory!\n\r");
00384     }
00385     sd.getlongname(name, last);     // if last file was match, return the last
00386                                     // if filename not found, return last
00387                                     // if no file in directory, return ""
00388 }
00389 
00390 /*
00391 void getfilename(char *name, int filenr) {
00392     extern LaosFileSystem sd;
00393     int cnt=0;
00394     DIR *d;
00395     struct dirent *p;
00396     d = opendir("/sd");
00397     if(d != NULL) {
00398         while((p = readdir(d)) != NULL) {
00399             if (strncmp(p->d_name, "longname.sy",11)) {
00400                 if (cnt++ == filenr) {
00401                     sd.getlongname(name, p->d_name);
00402                     closedir(d);
00403                     return;
00404                 }
00405             }
00406         } // while
00407         strcpy(name, "");
00408         closedir(d);
00409     } else {
00410         printf("Getfilename: Could not open directory!\n\r");
00411     }
00412 }
00413 
00414 int getfilenum(char *name) {
00415     extern LaosFileSystem sd;
00416     char shortname[SHORTFILESIZE];
00417     getshortname(shortname, name);
00418     int cnt=0;
00419     DIR *d;
00420     struct dirent *p;
00421     d = opendir("/sd");
00422     if(d != NULL) {
00423         while((p = readdir(d)) != NULL) {
00424             if (strncmp(p->d_name, "longname.sy",11)) {
00425                 if (!strcmp(shortname, name)) {
00426                     closedir(d);
00427                     return cnt;
00428                 }
00429                 cnt++;
00430             }
00431         } // while
00432         closedir(d);
00433         return 0;
00434     } else {
00435         printf("Getfilename: Could not open directory!\n\r");
00436     }
00437     return 0;
00438 }
00439 */
00440 
00441 void writefile(char *myfile) {
00442     extern LaosFileSystem sd;
00443     printf("Writing file %s\n\r", myfile);
00444     FILE *fp = sd.openfile(myfile, "wb");
00445     if (fp) {
00446         fclose(fp);
00447     } 
00448 }
00449 
00450 void removefile(char *name) {
00451     extern LaosFileSystem sd;
00452     char shortname[SHORTFILESIZE] = "";
00453     sd.getshortname(shortname, name);
00454     if (strlen(shortname) != 0) {
00455         char fullname[MAXFILESIZE+SHORTFILESIZE+1];
00456         sprintf(fullname, "%s%s", sd.pathname, shortname);
00457         if (remove(fullname) < 0)
00458             printf("Error while removing file %s\n\r", fullname);
00459         sd.cleanlist();           
00460     } 
00461 }
00462 
00463 // Read an integer from file
00464 int readint(FILE *fp)
00465 {
00466   unsigned short int i=0;
00467   int sign=1;
00468   char c, str[16];
00469   
00470   while( !feof(fp)  )
00471   {
00472     fread(&c, sizeof(c),1,fp);   
00473     
00474     switch(c)
00475     {
00476       case '0': case '1': case '2':  case '3':  case '4': 
00477       case '5': case '6': case '7':  case '8':  case '9':  
00478         if ( i < sizeof(str)) 
00479           str[i++] = (char)c;
00480         break;
00481       case '-': sign = -1; break;
00482       case ';': while ((!feof(fp)) && (c != '\n')) {
00483             fread(&c, sizeof(c),1,fp);
00484         }
00485         break; 
00486       case ' ': case '\t': case '\r': case '\n':
00487         if ( i )
00488         {
00489           int val=0, d=1;
00490           while(i) 
00491           {
00492             if ( str[i-1] == '-' ) 
00493               d *= -1;
00494             else
00495               val += (str[i-1]-'0') * d;
00496             d *= 10;
00497             i--;
00498           }
00499           val *= sign;
00500           return val;
00501         }
00502         break;
00503     } // Switch
00504   } // while
00505   return 0;
00506 } // read integer
00507 
00508 void strtolower(char *name) {
00509     for(int i = 0; i < strlen(name); i++)
00510         name[i] = tolower(name[i]);
00511 }
00512 
00513 int isFirmware(char *filename) {
00514     char name[MAXFILESIZE];
00515     strcpy(name, filename);
00516     strtolower(name);
00517     int x = strlen(name);
00518     if ((tolower(filename[--x])=='n') && (tolower(filename[--x])=='i') && (tolower(filename[--x])=='b') && (filename[--x]=='.'))
00519         return 1;
00520     else
00521         return 0;
00522 } 
00523 
00524 void installFirmware(char *filename) {
00525     removeFirmware();
00526     char buff[512];
00527     extern LaosFileSystem sd;
00528     //printf("Copy firmware file %s\n\r", filename);
00529     FILE *fp = sd.openfile(filename, "rb");
00530     if (fp) {
00531         FILE *fp2 = fopen("/local/firmware.bin", "wb");
00532         while (!feof(fp)) {
00533             int size = fread(buff, 1, 512, fp);
00534             fwrite(buff, 1, size, fp2);
00535         }
00536         fclose(fp);
00537         fclose(fp2);
00538     }
00539     removefile(filename);
00540 }
00541 
00542 void removeFirmware() { // remove old firmware from SD
00543     DIR *d;
00544     struct dirent *p;
00545     d = opendir("/local");
00546     if(d != NULL) {
00547         while((p = readdir(d)) != NULL) {
00548             if (isFirmware(p->d_name)) {
00549                 char name[32];
00550                 sprintf(name, "/local/%s", p->d_name);
00551                 remove(name);
00552             } 
00553         }
00554     } else {
00555         printf("removeFirmware: Could not open directory!\n\r");
00556     }
00557 }
00558 
00559 int SDcheckFirmware() {
00560     extern LaosFileSystem sd;
00561     DIR *d;
00562     struct dirent *p;
00563     d = opendir("/sd");
00564     if(d != NULL) {
00565         while((p = readdir(d)) != NULL) {
00566             if (strncmp(p->d_name, "longname.sy",11)) {
00567                 if (isFirmware(p->d_name)) {
00568                     installFirmware(p->d_name);
00569                     return 1;
00570                 }
00571             }
00572         }
00573     } else {
00574         printf("SDcheckFirmware: Could not open directory!\n\r");
00575     }
00576     return 0;
00577 }
00578 
00579 int isLaosFile(char *filename) {
00580     char name[MAXFILESIZE];
00581     strcpy(name, filename);
00582     strtolower(name);
00583     int x = strlen(name);
00584     if ((tolower(filename[--x])=='c') && (tolower(filename[--x])=='g') && (tolower(filename[--x])=='l') && (filename[--x]=='.'))
00585         return 1;
00586     else
00587         return 0;
00588 }