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
Diff: LaosFile/laosfilesystem.cpp
- Revision:
- 0:3852426a5068
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LaosFile/laosfilesystem.cpp Fri Jun 08 09:26:40 2012 +0000 @@ -0,0 +1,588 @@ +/* + * + * LaosFilesystem.cpp + * Simple Long Filename system on top of SDFilesystem.h + * + * Copyright (c) 2011 Jaap Vermaas + * + * This file is part of the LaOS project (see: http://wiki.laoslaser.org + * + * LaOS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LaOS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LaOS. If not, see <http://www.gnu.org/licenses/>. + * + */ +#include "laosfilesystem.h" + +LaosFileSystem::LaosFileSystem(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name) + : SDFileSystem(mosi, miso, sclk, cs, name) { + sprintf(tablename, "/%s/%s", name, _LAOSFILE_TRANSTABLE); + sprintf(pathname, "/%s/", name); +} + +LaosFileSystem::~LaosFileSystem() { +} + +FILE* LaosFileSystem::openfile(char *name, char* iom) { + if (islegalname(name)) { // check length and chars in name + + char shortname[SHORTFILESIZE] = ""; + getshortname(shortname, name); + char fullname[MAXFILESIZE+SHORTFILESIZE+1]; + if (strstr(iom, "r")) { // open file for reading + if (strlen(shortname)!=0) { + sprintf(fullname, "%s%s", pathname, shortname); + return fopen(fullname, iom); + } else { // no file exists + return NULL; + } + } else { // open file for writng + if (strlen(shortname)!=0) { + sprintf(fullname, "%s%s", pathname, shortname); + return fopen(fullname, iom); + } else { // create a new file + makeshortname(shortname, name); + sprintf(fullname, "%s%s", pathname, shortname); + return fopen(fullname, iom); + } + } + } else { // (islegalname(name)) + return NULL; + } +} + +void LaosFileSystem::getlongname(char *result, char *searchname) { + FILE *fp = fopen(tablename, "r"); + if (fp) { + char longname[MAXFILESIZE]; + char shortname[SHORTFILESIZE]; + while (dirread(longname, shortname, fp)) + if (! strcmp(shortname, searchname)) + break; + if (strcmp(shortname, searchname)) + strcpy(result, searchname); + else + strcpy(result, longname); + fclose(fp); + } else { + strcpy(result, searchname); + } +} + +int LaosFileSystem::islegalname(char* name) { + if (( strlen(name) > MAXFILESIZE-1 ) || (strlen(name) == 0)) + return 0; + int legal = 1; + char nochar[] = "?*,;=+#>|[]/\\"; + int x = 0; + while (legal && (name[x] != 0)) { + legal *= (name[x] > 32) && (name[x] < 126); + int y = 0; + while (legal && (nochar[y] != 0)) + legal *= name[x] != nochar[y++]; + x++; + } + return legal; +} + +int LaosFileSystem::isshortname(char* name) { + int len = strlen(name); + for (int x=0; x<len; x++) + if (name[x] == ' ') return 0; // spaces not allowed in shortname + + char myname[MAXFILESIZE]; + strcpy(myname, name); + char *basename = NULL; + if (len <= SHORTFILESIZE-1) { + basename = strtok(myname, "."); + if (strlen(basename) > 8) { + return 0; // basename was too long + } else { + if (char *ext_name = strtok(NULL, ".")) { // + if ((strlen(basename)+strlen(ext_name)+1) == len) { + if (strlen(ext_name)<4) { + return 1; // filename is in 8.3 format + } else { + return 0; // extension too long + } + } else { + return 0; // there was more then one dot + } + } else { + return 1; // filename of max 8 chars, no extension (OK) + } + } + } else { + return 0; // total filename too long + } +} + +void LaosFileSystem::removespaces(char* name) { + int spaces = 1; + while (spaces) { + spaces = 0; + int x = 0; + while ((name[x] != ' ') && (x<strlen(name))) x++; + if (name[x] == ' ') { + spaces = 1; + for (int y = x; x<(strlen(name)-1); y++) + name[y] = name[y+1]; + } + } +} + +void LaosFileSystem::getshortname(char* shortname, char* name) { + // * open filename translation table + // * and see if a file with that name exists + if (isshortname(name)) { + strcpy(shortname, name); + } else { + int found = 0; + char longname[MAXFILESIZE]; + FILE *fp = fopen(tablename, "r"); + if (fp) { + while (dirread(longname, shortname, fp)) { + if (!strcmp(longname, name)) { + found = 1; + break; + } + } + if (! found) strcpy(shortname, ""); + fclose(fp); + } + } +} + +void LaosFileSystem::makeshortname(char* shortname, char* name) { + char *tmpname = new char[MAXFILESIZE]; + strcpy(tmpname, name); + removespaces(tmpname); + shorten(tmpname, SHORTFILESIZE); + char *basename = strtok(tmpname, "."); + char *ext_name = strtok(NULL, "."); + strtolower(basename); + strtolower(ext_name); + int cnt = 1; + char fullname[MAXFILESIZE+SHORTFILESIZE+2]; + FILE *fp = NULL; + do { + if (fp != NULL) fclose(fp); + while ((cnt/10+strlen(basename)+2) > 8) + basename[strlen(basename)-1] = 0; + if (strlen(ext_name) > 0) { + sprintf(shortname, "%s~%d.%s", basename, cnt++, ext_name); + } else { + sprintf(shortname, "%s~%d", basename, cnt++); + } + sprintf(fullname, "%s%s", pathname, shortname); + fp = fopen(fullname, "rb"); + } while (fp!=NULL); + + FILE *tfp = fopen(tablename, "ab"); + dirwrite(name, shortname, tfp); + fclose(tfp); + + delete(tmpname); +} + +void LaosFileSystem::cleanlist() { + // * open filename translation table + char longname[MAXFILESIZE]; + char shortname[SHORTFILESIZE]; + char tabletmpname[MAXFILESIZE+SHORTFILESIZE+1]; + strcpy (tabletmpname, tablename); + tabletmpname[strlen(tabletmpname)-1] = '~'; + + // make a full copy of the table + FILE* fp1 = fopen(tablename, "rb"); + if (fp1 == NULL) return; + FILE* fp2 = fopen(tabletmpname, "wb"); + if (fp2 == NULL) return; + while (dirread(longname, shortname, fp1)) + dirwrite(longname, shortname, fp2); + fclose(fp1); + fclose(fp2); + + fp1 = fopen(tablename, "wb"); + if (fp1 == NULL) return; + fp2 = fopen(tabletmpname, "rb"); + if (fp2 == NULL) return; + FILE* fp; + while (dirread(longname, shortname, fp2)) { + char fullname[MAXFILESIZE+SHORTFILESIZE+1]; + sprintf(fullname, "%s%s", pathname, shortname); + fp = fopen(fullname, "rb"); + if (fp != NULL) { + fclose(fp); + dirwrite(longname, shortname, fp1); + } + } + fclose(fp1); + fclose(fp2); +} + +void LaosFileSystem::shorten(char* name, int max) { + int len = 0; + while (name[len++] != 0); /* end of string */ + len--; + if (len > max-1) { + int ext = len; + while (name[--ext] != '.'); /* begin of extension */ + int baselen, extlen; + baselen = ext; + extlen = len-ext-1; + while ((baselen > max-5) && (baselen+extlen+1 > max-1)) + baselen--; + name[baselen++] = '.'; + while ((ext<len) && (baselen < max-1)) + name[baselen++] = name[++ext]; + name[baselen] = 0; + } +} + +size_t LaosFileSystem::dirread(char* longname, char* shortname, FILE *fp) { + char buff[MAXFILESIZE+SHORTFILESIZE]; + size_t result = fread(buff, 1, MAXFILESIZE+SHORTFILESIZE, fp); + if (result) { + strncpy(longname, buff, MAXFILESIZE); + longname[MAXFILESIZE-1] = 0; + int cnt = MAXFILESIZE-2; + while (longname[cnt]==' ') longname[cnt--] = 0; + + strncpy(shortname, &buff[MAXFILESIZE], SHORTFILESIZE); + shortname[SHORTFILESIZE-1] = 0; + cnt = SHORTFILESIZE-2; + while (shortname[cnt]==' ') shortname[cnt--] = 0; + } + return result; +} + +size_t LaosFileSystem::dirwrite(char* longname, char* shortname, FILE* fp) { + char buff[MAXFILESIZE+SHORTFILESIZE]; + int x=0; + while (longname[x] != 0) buff[x++] = longname[x]; + while (x<MAXFILESIZE-1) buff[x++] = ' '; + buff[x++] = '\t'; + while (shortname[x-MAXFILESIZE] != 0) buff[x++] = shortname[x-MAXFILESIZE]; + while (x<MAXFILESIZE+SHORTFILESIZE-1) buff[x++] = ' '; + buff[x++] = '\n'; + + return fwrite(buff, 1, MAXFILESIZE+SHORTFILESIZE, fp); +} + +void showfile() { + char buff[35]; + FILE *fp = fopen("/sd/longname.sys","rb"); + if (fp) { + printf("Contents of longname.sys\n\r"); + while (fread(buff, 1, MAXFILESIZE+SHORTFILESIZE, fp)) + printf("> %s\r", buff); + fclose(fp); + printf("\n\r"); + } +} + +void cleandir() { + DIR *d; + struct dirent *p; + d = opendir("/sd"); + if(d != NULL) { + while((p = readdir(d)) != NULL) { + char fullname[MAXFILESIZE+SHORTFILESIZE+2]; + sprintf(fullname, "/sd/%s", p->d_name); + remove(fullname); + } + } else { + error("Could not open directory!\n\r"); + } +} + +void printdir() { + extern LaosFileSystem sd; + printf("List of files in /sd\n\r"); + DIR *d; + struct dirent *p; + d = opendir("/sd"); + if(d != NULL) { + // printf("...\n\r"); + while((p = readdir(d)) != NULL) { + // printf("Short %s\n\r", p->d_name); + if (strncmp(p->d_name, "longname.sy",11)) { + char longname[MAXFILESIZE]; + // printf("Getlongname\n\r"); + sd.getlongname(longname, p->d_name); + printf(" - %s (short: %s)\n\r", longname, p->d_name); + } + } + } else { + printf("Could not open directory!\n\r"); + } +} + +void getprevjob(char *name) { + extern LaosFileSystem sd; + char shortname[SHORTFILESIZE], last[SHORTFILESIZE]; + strcpy(last, ""); + sd.getshortname(shortname, name); + DIR *d; + struct dirent *p; + d = opendir("/sd"); + if(d != NULL) { + while((p = readdir(d)) != NULL) { + if (strncmp(p->d_name, "longname.sy",11)) { // skip longname.sy* + if (! strcmp(shortname, p->d_name)) { // shortname = current entry + if (strcmp(last, "")) { + sd.getlongname(name, last); // return entry before + } else { + sd.getlongname(name, p->d_name); // last="", so current = first + } + closedir(d); + return; + } + strcpy(last, p->d_name); + } + } // while + closedir(d); + } else { + printf("Getfilename: Could not open directory!\n\r"); + } + sd.getlongname(name, last); // name not found (return last) + // or no file found (return "") +} + +void getnextjob(char *name) { + extern LaosFileSystem sd; + char shortname[SHORTFILESIZE], last[SHORTFILESIZE]; + strcpy(last, ""); + sd.getshortname(shortname, name); + DIR *d; + struct dirent *p; + d = opendir("/sd"); + if(d != NULL) { + while((p = readdir(d)) != NULL) { + if (strncmp(p->d_name, "longname.sy",11)) { // skip longname.sy* + if (! strcmp(shortname, last)) { // if last was shortname + sd.getlongname(name, p->d_name); // return current + closedir(d); + return; + } + strcpy(last, p->d_name); + } + } // while + closedir(d); + } else { + printf("Getfilename: Could not open directory!\n\r"); + } + sd.getlongname(name, last); // if last file was match, return the last + // if filename not found, return last + // if no file in directory, return "" +} + +/* +void getfilename(char *name, int filenr) { + extern LaosFileSystem sd; + int cnt=0; + DIR *d; + struct dirent *p; + d = opendir("/sd"); + if(d != NULL) { + while((p = readdir(d)) != NULL) { + if (strncmp(p->d_name, "longname.sy",11)) { + if (cnt++ == filenr) { + sd.getlongname(name, p->d_name); + closedir(d); + return; + } + } + } // while + strcpy(name, ""); + closedir(d); + } else { + printf("Getfilename: Could not open directory!\n\r"); + } +} + +int getfilenum(char *name) { + extern LaosFileSystem sd; + char shortname[SHORTFILESIZE]; + getshortname(shortname, name); + int cnt=0; + DIR *d; + struct dirent *p; + d = opendir("/sd"); + if(d != NULL) { + while((p = readdir(d)) != NULL) { + if (strncmp(p->d_name, "longname.sy",11)) { + if (!strcmp(shortname, name)) { + closedir(d); + return cnt; + } + cnt++; + } + } // while + closedir(d); + return 0; + } else { + printf("Getfilename: Could not open directory!\n\r"); + } + return 0; +} +*/ + +void writefile(char *myfile) { + extern LaosFileSystem sd; + printf("Writing file %s\n\r", myfile); + FILE *fp = sd.openfile(myfile, "wb"); + if (fp) { + fclose(fp); + } +} + +void removefile(char *name) { + extern LaosFileSystem sd; + char shortname[SHORTFILESIZE] = ""; + sd.getshortname(shortname, name); + if (strlen(shortname) != 0) { + char fullname[MAXFILESIZE+SHORTFILESIZE+1]; + sprintf(fullname, "%s%s", sd.pathname, shortname); + if (remove(fullname) < 0) + printf("Error while removing file %s\n\r", fullname); + sd.cleanlist(); + } +} + +// Read an integer from file +int readint(FILE *fp) +{ + unsigned short int i=0; + int sign=1; + char c, str[16]; + + while( !feof(fp) ) + { + fread(&c, sizeof(c),1,fp); + + switch(c) + { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + if ( i < sizeof(str)) + str[i++] = (char)c; + break; + case '-': sign = -1; break; + case ';': while ((!feof(fp)) && (c != '\n')) { + fread(&c, sizeof(c),1,fp); + } + break; + case ' ': case '\t': case '\r': case '\n': + if ( i ) + { + int val=0, d=1; + while(i) + { + if ( str[i-1] == '-' ) + d *= -1; + else + val += (str[i-1]-'0') * d; + d *= 10; + i--; + } + val *= sign; + return val; + } + break; + } // Switch + } // while + return 0; +} // read integer + +void strtolower(char *name) { + for(int i = 0; i < strlen(name); i++) + name[i] = tolower(name[i]); +} + +int isFirmware(char *filename) { + char name[MAXFILESIZE]; + strcpy(name, filename); + strtolower(name); + int x = strlen(name); + if ((tolower(filename[--x])=='n') && (tolower(filename[--x])=='i') && (tolower(filename[--x])=='b') && (filename[--x]=='.')) + return 1; + else + return 0; +} + +void installFirmware(char *filename) { + removeFirmware(); + char buff[512]; + extern LaosFileSystem sd; + //printf("Copy firmware file %s\n\r", filename); + FILE *fp = sd.openfile(filename, "rb"); + if (fp) { + FILE *fp2 = fopen("/local/firmware.bin", "wb"); + while (!feof(fp)) { + int size = fread(buff, 1, 512, fp); + fwrite(buff, 1, size, fp2); + } + fclose(fp); + fclose(fp2); + } + removefile(filename); +} + +void removeFirmware() { // remove old firmware from SD + DIR *d; + struct dirent *p; + d = opendir("/local"); + if(d != NULL) { + while((p = readdir(d)) != NULL) { + if (isFirmware(p->d_name)) { + char name[32]; + sprintf(name, "/local/%s", p->d_name); + remove(name); + } + } + } else { + printf("removeFirmware: Could not open directory!\n\r"); + } +} + +int SDcheckFirmware() { + extern LaosFileSystem sd; + DIR *d; + struct dirent *p; + d = opendir("/sd"); + if(d != NULL) { + while((p = readdir(d)) != NULL) { + if (strncmp(p->d_name, "longname.sy",11)) { + if (isFirmware(p->d_name)) { + installFirmware(p->d_name); + return 1; + } + } + } + } else { + printf("SDcheckFirmware: Could not open directory!\n\r"); + } + return 0; +} + +int isLaosFile(char *filename) { + char name[MAXFILESIZE]; + strcpy(name, filename); + strtolower(name); + int x = strlen(name); + if ((tolower(filename[--x])=='c') && (tolower(filename[--x])=='g') && (tolower(filename[--x])=='l') && (filename[--x]=='.')) + return 1; + else + return 0; +}