/* * FreeRTOS+FAT SL V1.0.1 (C) 2014 HCC Embedded * * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license * terms. * * FreeRTOS+FAT SL uses a dual license model that allows the software to be used * under a standard GPL open source license, or a commercial license. The * standard GPL license (unlike the modified GPL license under which FreeRTOS * itself is distributed) requires that all software statically linked with * FreeRTOS+FAT SL is also distributed under the same GPL V2 license terms. * Details of both license options follow: * * - Open source licensing - * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and * distributed without charge provided the user adheres to version two of the * GNU General Public License (GPL) and does not remove the copyright notice or * this text. The GPL V2 text is available on the gnu.org web site, and on the * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. * * - Commercial licensing - * Businesses and individuals who for commercial or other reasons cannot comply * with the terms of the GPL V2 license must obtain a commercial license before * incorporating FreeRTOS+FAT SL into proprietary software for distribution in * any form. Commercial licenses can be purchased from * http://shop.freertos.org/fat_sl and do not require any source files to be * changed. * * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all * conditions and terms, be they implied, expressed, or statutory. * * http://www.FreeRTOS.org * http://www.FreeRTOS.org/FreeRTOS-Plus * */ #include "../../api/fat_sl.h" #include "util.h" #include "../../version/ver_fat_sl.h" #if VER_FAT_SL_MAJOR != 5 || VER_FAT_SL_MINOR != 2 #error Incompatible FAT_SL version number! #endif /**************************************************************************** * * _f_checknameprim * * checking a string if could be valid * * INPUTS * * ptr - pointer to name or extension * len - number max char of name or extension * * RETURNS * ***************************************************************************/ static unsigned char _f_checknameprim ( char * ptr, unsigned char len ) { unsigned char inspace = 0; while ( len-- ) { char ch = *ptr++; if ( !inspace ) { if ( ch == ' ' ) { inspace = 1; } if ( ( ch == '|' ) || ( ch == '[' ) || ( ch == ']' ) || ( ch == '<' ) || ( ch == '>' ) || ( ch == '/' ) || ( ch == '\\' ) || ( ch == ':' ) ) { return 1; } } else if ( ch != ' ' ) { return 1; /*no inspace allowed*/ } } return 0; } /* _f_checknameprim */ /**************************************************************************** * * _f_checkname * * checking filename and extension for special characters * * INPUTS * * name - filename (e.g.: filename) * ext - extension of file (e.g.: txt) * * RETURNS * * 0 - if no contains invalid character * other - if contains any invalid character * ***************************************************************************/ unsigned char _f_checkname ( char * name, char * ext ) { if ( _f_checknameprim( name, F_MAXNAME ) ) { return 1; } if ( _f_checknameprim( ext, F_MAXEXT ) ) { return 1; } return 0; } /**************************************************************************** * * _f_checknamewc * * checking filename and extension for wildcard character * * INPUTS * * name - filename (e.g.: filename) * ext - extension of file (e.g.: txt) * * RETURNS * * 0 - if no contains wildcard character (? or *) * other - if contains any wildcard character * ***************************************************************************/ unsigned char _f_checknamewc ( const char * name, const char * ext ) { unsigned char a = 0; for ( a = 0 ; a < F_MAXNAME ; a++ ) { char ch = name[a]; if ( ( ch == '?' ) || ( ch == '*' ) ) { return 1; } } for ( a = 0 ; a < F_MAXEXT ; a++ ) { char ch = ext[a]; if ( ( ch == '?' ) || ( ch == '*' ) ) { return 1; } } return _f_checkname( (char *)name, (char *)ext ); } /* _f_checknamewc */ /**************************************************************************** * * _f_setnameext * * convert a string into filename and extension separatelly, the terminator * character could be zero char, '/' or '\' * * INPUTS * * s - source string (e.g.: hello.txt) * name - where to store name (this array size has to be F_MAXNAME (8)) * ext - where to store extension (this array size has to be F_MAXEXT (3)) * * RETURNS * * length of the used bytes from source string array * ***************************************************************************/ unsigned char _f_setnameext ( char * s, char * name, char * ext ) { unsigned char len, extlen = 0; unsigned char a; unsigned char setext = 1; for ( len = 0 ; ; ) { unsigned char ch = s[len]; if ( ( ch == 0 ) || ( ch == '\\' ) || ( ch == '/' ) ) { break; } len++; /*calculate len*/ } if ( len && ( s[0] == '.' ) ) { /* if (len==1 || (s[1]=='.' && len==2)) goto dots; */ if ( ( len == 1 ) || ( s[1] == '.' ) ) { goto dots; } } for ( a = len ; a ; a-- ) { if ( s[a - 1] == '.' ) { unsigned char b; extlen = (unsigned char)( len - a + 1 ); len = (unsigned char)( a - 1 ); for ( b = 0 ; b < F_MAXEXT ; b++ ) { if ( b < extlen - 1 ) { ext[b] = _f_toupper( s[a++] ); } else { ext[b] = ' '; } } setext = 0; break; } } dots: if ( setext ) { for ( a = 0 ; a < F_MAXEXT ; a++ ) { ext[a] = ' '; } } for ( a = 0 ; a < F_MAXNAME ; a++ ) { if ( a < len ) { name[a] = _f_toupper( s[a] ); } else { name[a] = ' '; } } return (unsigned char)( len + extlen ); } /* _f_setnameext */ /**************************************************************************** * * _f_setfsname * * convert a single string into F_NAME structure * * INPUTS * * name - combined name with drive,path,filename,extension used for source * fsname - where to fill this structure with separated drive,path,name,ext * * RETURNS * * 0 - if successfully * other - if name contains invalid path or name * ***************************************************************************/ unsigned char _f_setfsname ( const char * name, F_NAME * fsname ) { char s[F_MAXPATH]; unsigned char namepos = 0; unsigned char pathpos = 0; unsigned char a; s[0] = 0; if ( !name[0] ) { return 1; /*no name*/ } if ( name[1] == ':' ) { name += 2; } if ( ( name[0] != '/' ) && ( name[0] != '\\' ) ) { if ( fn_getcwd( fsname->path, F_MAXPATH, 0 ) ) { return 1; /*error*/ } for ( pathpos = 0 ; fsname->path[pathpos] ; ) { pathpos++; } } for ( ; ; ) { char ch = _f_toupper( *name++ ); if ( !ch ) { break; } if ( ch == ':' ) { return 1; /*not allowed*/ } if ( ( ch == '/' ) || ( ch == '\\' ) ) { if ( pathpos ) { if ( fsname->path[pathpos - 1] == '/' ) { return 1; /*not allowed double */ } if ( pathpos >= F_MAXPATH - 2 ) { return 1; /*path too long*/ } fsname->path[pathpos++] = '/'; } for ( ; namepos ; ) { if ( s[namepos - 1] != ' ' ) { break; } namepos--; /*remove end spaces*/ } for ( a = 0 ; a < namepos ; a++ ) { if ( pathpos >= F_MAXPATH - 2 ) { return 1; /*path too long*/ } fsname->path[pathpos++] = s[a]; } namepos = 0; continue; } if ( ( ch == ' ' ) && ( !namepos ) ) { continue; /*remove start spaces*/ } if ( namepos >= ( sizeof( s ) - 2 ) ) { return 1; /*name too long*/ } s[namepos++] = ch; } s[namepos] = 0; /*terminates it*/ fsname->path[pathpos] = 0; /*terminates it*/ for ( ; namepos ; ) { if ( s[namepos - 1] != ' ' ) { break; } s[namepos - 1] = 0; /*remove end spaces*/ namepos--; } if ( !_f_setnameext( s, fsname->filename, fsname->fileext ) ) { return 2; /*no name*/ } if ( fsname->filename[0] == ' ' ) { return 1; /*cannot be*/ } return 0; } /* _f_setfsname */ /**************************************************************************** * * _f_createfullname * * create full name * * INPUTS * * buffer - where to create * buffersize - size of the buffer * drivenum - drive number * path - path of the file * filename - file name * fileext - file extension * * RETURNS * * 1 - if found and osize is filled * 0 - not found * ***************************************************************************/ int _f_createfullname ( char * buffer, int buffersize, char * path, char * filename, char * fileext ) { char * fullname = buffer; int a; /* adding drive letter */ if ( buffersize < 1 ) { return 1; } *fullname++ = '/'; buffersize -= 1; /* adding path */ if ( path[0] ) { for ( ; ; ) { char ch = *path++; if ( !ch ) { break; } if ( buffersize <= 0 ) { return 1; } *fullname++ = ch; buffersize--; } /* adding separator */ if ( buffersize <= 0 ) { return 1; } *fullname++ = '/'; } /* adding name */ for ( a = 0 ; a < F_MAXNAME ; a++ ) { char ch = *filename++; if ( ( !ch ) || ( ch == 32 ) ) { break; } if ( buffersize <= 0 ) { return 1; } *fullname++ = ch; buffersize--; } /* adding ext*/ if ( fileext[0] && ( fileext[0] != 32 ) ) { /* adding dot */ if ( !buffersize ) { return 1; } *fullname++ = '.'; for ( a = 0 ; a < F_MAXEXT ; a++ ) { char ch = *fileext++; if ( ( !ch ) || ( ch == 32 ) ) { break; } if ( buffersize <= 0 ) { return 1; } *fullname++ = ch; buffersize--; } } /* adding terminator */ if ( buffersize <= 0 ) { return 1; } *fullname++ = 0; return 0; } /* _f_createfullname */