]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/util_sfn.c
Update FreeRTOS+FAT SL to version 1.0.1.
[freertos] / FreeRTOS-Plus / Source / FreeRTOS-Plus-FAT-SL / fat_sl / common / util_sfn.c
1 /*\r
2  * FreeRTOS+FAT SL V1.0.1 (C) 2014 HCC Embedded\r
3  *\r
4  * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
5  * terms.\r
6  * \r
7  * FreeRTOS+FAT SL uses a dual license model that allows the software to be used \r
8  * under a standard GPL open source license, or a commercial license.  The \r
9  * standard GPL license (unlike the modified GPL license under which FreeRTOS \r
10  * itself is distributed) requires that all software statically linked with \r
11  * FreeRTOS+FAT SL is also distributed under the same GPL V2 license terms.  \r
12  * Details of both license options follow:\r
13  * \r
14  * - Open source licensing -\r
15  * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
16  * distributed without charge provided the user adheres to version two of the \r
17  * GNU General Public License (GPL) and does not remove the copyright notice or \r
18  * this text.  The GPL V2 text is available on the gnu.org web site, and on the\r
19  * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
20  * \r
21  * - Commercial licensing -\r
22  * Businesses and individuals who for commercial or other reasons cannot comply\r
23  * with the terms of the GPL V2 license must obtain a commercial license before \r
24  * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
25  * any form.  Commercial licenses can be purchased from \r
26  * http://shop.freertos.org/fat_sl and do not require any source files to be \r
27  * changed.\r
28  *\r
29  * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You\r
30  * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
31  * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
32  * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
33  * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
34  * conditions and terms, be they implied, expressed, or statutory.\r
35  *\r
36  * http://www.FreeRTOS.org\r
37  * http://www.FreeRTOS.org/FreeRTOS-Plus\r
38  *\r
39  */\r
40 \r
41 #include "../../api/fat_sl.h"\r
42 \r
43 #include "util.h"\r
44 \r
45 #include "../../version/ver_fat_sl.h"\r
46 #if VER_FAT_SL_MAJOR != 5 || VER_FAT_SL_MINOR != 2\r
47  #error Incompatible FAT_SL version number!\r
48 #endif\r
49 \r
50 \r
51 \r
52 /****************************************************************************\r
53  *\r
54  * _f_checknameprim\r
55  *\r
56  * checking a string if could be valid\r
57  *\r
58  * INPUTS\r
59  *\r
60  * ptr - pointer to name or extension\r
61  * len - number max char of name or extension\r
62  *\r
63  * RETURNS\r
64  *\r
65  ***************************************************************************/\r
66 static unsigned char _f_checknameprim ( char * ptr, unsigned char len )\r
67 {\r
68   unsigned char  inspace = 0;\r
69 \r
70   while ( len-- )\r
71   {\r
72     char  ch = *ptr++;\r
73     if ( !inspace )\r
74     {\r
75       if ( ch == ' ' )\r
76       {\r
77         inspace = 1;\r
78       }\r
79 \r
80       if ( ( ch == '|' ) || ( ch == '[' ) || ( ch == ']' ) || ( ch == '<' ) || ( ch == '>' ) || ( ch == '/' ) || ( ch == '\\' ) || ( ch == ':' ) )\r
81       {\r
82         return 1;\r
83       }\r
84     }\r
85     else if ( ch != ' ' )\r
86     {\r
87       return 1;                     /*no inspace allowed*/\r
88     }\r
89   }\r
90 \r
91   return 0;\r
92 } /* _f_checknameprim */\r
93 \r
94 \r
95 /****************************************************************************\r
96  *\r
97  * _f_checkname\r
98  *\r
99  * checking filename and extension for special characters\r
100  *\r
101  * INPUTS\r
102  *\r
103  * name - filename (e.g.: filename)\r
104  * ext - extension of file (e.g.: txt)\r
105  *\r
106  * RETURNS\r
107  *\r
108  * 0 - if no contains invalid character\r
109  * other - if contains any invalid character\r
110  *\r
111  ***************************************************************************/\r
112 unsigned char _f_checkname ( char * name, char * ext )\r
113 {\r
114   if ( _f_checknameprim( name, F_MAXNAME ) )\r
115   {\r
116     return 1;\r
117   }\r
118 \r
119   if ( _f_checknameprim( ext, F_MAXEXT ) )\r
120   {\r
121     return 1;\r
122   }\r
123 \r
124   return 0;\r
125 }\r
126 \r
127 \r
128 /****************************************************************************\r
129  *\r
130  * _f_checknamewc\r
131  *\r
132  * checking filename and extension for wildcard character\r
133  *\r
134  * INPUTS\r
135  *\r
136  * name - filename (e.g.: filename)\r
137  * ext - extension of file (e.g.: txt)\r
138  *\r
139  * RETURNS\r
140  *\r
141  * 0 - if no contains wildcard character (? or *)\r
142  * other - if contains any wildcard character\r
143  *\r
144  ***************************************************************************/\r
145 unsigned char _f_checknamewc ( const char * name, const char * ext )\r
146 {\r
147   unsigned char  a = 0;\r
148 \r
149   for ( a = 0 ; a < F_MAXNAME ; a++ )\r
150   {\r
151     char  ch = name[a];\r
152     if ( ( ch == '?' ) || ( ch == '*' ) )\r
153     {\r
154       return 1;\r
155     }\r
156   }\r
157 \r
158   for ( a = 0 ; a < F_MAXEXT ; a++ )\r
159   {\r
160     char  ch = ext[a];\r
161     if ( ( ch == '?' ) || ( ch == '*' ) )\r
162     {\r
163       return 1;\r
164     }\r
165   }\r
166 \r
167   return _f_checkname( (char *)name, (char *)ext );\r
168 } /* _f_checknamewc */\r
169 \r
170 \r
171 \r
172 \r
173 /****************************************************************************\r
174  *\r
175  * _f_setnameext\r
176  *\r
177  * convert a string into filename and extension separatelly, the terminator\r
178  * character could be zero char, '/' or '\'\r
179  *\r
180  * INPUTS\r
181  *\r
182  * s - source string (e.g.: hello.txt)\r
183  * name - where to store name (this array size has to be F_MAXNAME (8))\r
184  * ext - where to store extension (this array size has to be F_MAXEXT (3))\r
185  *\r
186  * RETURNS\r
187  *\r
188  * length of the used bytes from source string array\r
189  *\r
190  ***************************************************************************/\r
191 unsigned char _f_setnameext ( char * s, char * name, char * ext )\r
192 {\r
193   unsigned char  len, extlen = 0;\r
194   unsigned char  a;\r
195   unsigned char  setext = 1;\r
196 \r
197   for ( len = 0 ; ; )\r
198   {\r
199     unsigned char  ch = s[len];\r
200     if ( ( ch == 0 ) || ( ch == '\\' ) || ( ch == '/' ) )\r
201     {\r
202       break;\r
203     }\r
204 \r
205     len++;                      /*calculate len*/\r
206   }\r
207 \r
208   if ( len && ( s[0] == '.' ) )\r
209   {\r
210 /*              if (len==1 || (s[1]=='.' && len==2)) goto dots;         */\r
211     if ( ( len == 1 ) || ( s[1] == '.' ) )\r
212     {\r
213       goto dots;\r
214     }\r
215   }\r
216 \r
217   for ( a = len ; a ; a-- )\r
218   {\r
219     if ( s[a - 1] == '.' )\r
220     {\r
221       unsigned char  b;\r
222 \r
223       extlen = (unsigned char)( len - a + 1 );\r
224       len = (unsigned char)( a - 1 );\r
225 \r
226       for ( b = 0 ; b < F_MAXEXT ; b++ )\r
227       {\r
228         if ( b < extlen - 1 )\r
229         {\r
230           ext[b] = _f_toupper( s[a++] );\r
231         }\r
232         else\r
233         {\r
234           ext[b] = ' ';\r
235         }\r
236       }\r
237 \r
238       setext = 0;\r
239       break;\r
240     }\r
241   }\r
242 \r
243 dots:\r
244   if ( setext )\r
245   {\r
246     for ( a = 0 ; a < F_MAXEXT ; a++ )\r
247     {\r
248       ext[a] = ' ';\r
249     }\r
250   }\r
251 \r
252   for ( a = 0 ; a < F_MAXNAME ; a++ )\r
253   {\r
254     if ( a < len )\r
255     {\r
256       name[a] = _f_toupper( s[a] );\r
257     }\r
258     else\r
259     {\r
260       name[a] = ' ';\r
261     }\r
262   }\r
263 \r
264   return (unsigned char)( len + extlen );\r
265 } /* _f_setnameext */\r
266 \r
267 \r
268 \r
269 /****************************************************************************\r
270  *\r
271  * _f_setfsname\r
272  *\r
273  * convert a single string into F_NAME structure\r
274  *\r
275  * INPUTS\r
276  *\r
277  * name - combined name with drive,path,filename,extension used for source\r
278  * fsname - where to fill this structure with separated drive,path,name,ext\r
279  *\r
280  * RETURNS\r
281  *\r
282  * 0 - if successfully\r
283  * other - if name contains invalid path or name\r
284  *\r
285  ***************************************************************************/\r
286 unsigned char _f_setfsname ( const char * name, F_NAME * fsname )\r
287 {\r
288   char           s[F_MAXPATH];\r
289   unsigned char  namepos = 0;\r
290 \r
291   unsigned char  pathpos = 0;\r
292   unsigned char  a;\r
293 \r
294   s[0] = 0;\r
295 \r
296   if ( !name[0] )\r
297   {\r
298     return 1;               /*no name*/\r
299   }\r
300 \r
301   if ( name[1] == ':' )\r
302   {\r
303     name += 2;\r
304   }\r
305 \r
306   if ( ( name[0] != '/' ) && ( name[0] != '\\' ) )\r
307   {\r
308     if ( fn_getcwd( fsname->path, F_MAXPATH, 0 ) )\r
309     {\r
310       return 1;                                            /*error*/\r
311     }\r
312 \r
313     for ( pathpos = 0 ; fsname->path[pathpos] ; )\r
314     {\r
315       pathpos++;\r
316     }\r
317   }\r
318 \r
319 \r
320   for ( ; ; )\r
321   {\r
322     char  ch = _f_toupper( *name++ );\r
323 \r
324     if ( !ch )\r
325     {\r
326       break;\r
327     }\r
328 \r
329     if ( ch == ':' )\r
330     {\r
331       return 1;                /*not allowed*/\r
332     }\r
333 \r
334     if ( ( ch == '/' ) || ( ch == '\\' ) )\r
335     {\r
336       if ( pathpos )\r
337       {\r
338         if ( fsname->path[pathpos - 1] == '/' )\r
339         {\r
340           return 1;                                         /*not allowed double */\r
341         }\r
342 \r
343         if ( pathpos >= F_MAXPATH - 2 )\r
344         {\r
345           return 1;                                 /*path too long*/\r
346         }\r
347 \r
348         fsname->path[pathpos++] = '/';\r
349       }\r
350 \r
351       for ( ; namepos ; )\r
352       {\r
353         if ( s[namepos - 1] != ' ' )\r
354         {\r
355           break;\r
356         }\r
357 \r
358         namepos--;                /*remove end spaces*/\r
359       }\r
360 \r
361       for ( a = 0 ; a < namepos ; a++ )\r
362       {\r
363         if ( pathpos >= F_MAXPATH - 2 )\r
364         {\r
365           return 1;                                 /*path too long*/\r
366         }\r
367 \r
368         fsname->path[pathpos++] = s[a];\r
369       }\r
370 \r
371       namepos = 0;\r
372       continue;\r
373     }\r
374 \r
375     if ( ( ch == ' ' ) && ( !namepos ) )\r
376     {\r
377       continue;                              /*remove start spaces*/\r
378     }\r
379 \r
380     if ( namepos >= ( sizeof( s ) - 2 ) )\r
381     {\r
382       return 1;                               /*name too long*/\r
383     }\r
384 \r
385     s[namepos++] = ch;\r
386   }\r
387 \r
388   s[namepos] = 0; /*terminates it*/\r
389   fsname->path[pathpos] = 0;  /*terminates it*/\r
390 \r
391   for ( ; namepos ; )\r
392   {\r
393     if ( s[namepos - 1] != ' ' )\r
394     {\r
395       break;\r
396     }\r
397 \r
398     s[namepos - 1] = 0; /*remove end spaces*/\r
399     namepos--;\r
400   }\r
401 \r
402   if ( !_f_setnameext( s, fsname->filename, fsname->fileext ) )\r
403   {\r
404     return 2;                                                         /*no name*/\r
405   }\r
406 \r
407   if ( fsname->filename[0] == ' ' )\r
408   {\r
409     return 1;                               /*cannot be*/\r
410   }\r
411 \r
412   return 0;\r
413 } /* _f_setfsname */\r
414 \r
415 \r
416 /****************************************************************************\r
417  *\r
418  * _f_createfullname\r
419  *\r
420  * create full name\r
421  *\r
422  * INPUTS\r
423  *\r
424  * buffer - where to create\r
425  * buffersize - size of the buffer\r
426  * drivenum - drive number\r
427  * path - path of the file\r
428  * filename - file name\r
429  * fileext - file extension\r
430  *\r
431  * RETURNS\r
432  *\r
433  * 1 - if found and osize is filled\r
434  * 0 - not found\r
435  *\r
436  ***************************************************************************/\r
437 int _f_createfullname ( char * buffer, int buffersize, char * path, char * filename, char * fileext )\r
438 {\r
439   char * fullname = buffer;\r
440   int    a;\r
441 \r
442   /* adding drive letter */\r
443   if ( buffersize < 1 )\r
444   {\r
445     return 1;\r
446   }\r
447 \r
448   *fullname++ = '/';\r
449   buffersize -= 1;\r
450 \r
451   /* adding path */\r
452   if ( path[0] )\r
453   {\r
454     for ( ; ; )\r
455     {\r
456       char  ch = *path++;\r
457 \r
458       if ( !ch )\r
459       {\r
460         break;\r
461       }\r
462 \r
463       if ( buffersize <= 0 )\r
464       {\r
465         return 1;\r
466       }\r
467 \r
468       *fullname++ = ch;\r
469       buffersize--;\r
470     }\r
471 \r
472     /* adding separator */\r
473     if ( buffersize <= 0 )\r
474     {\r
475       return 1;\r
476     }\r
477 \r
478     *fullname++ = '/';\r
479   }\r
480 \r
481   /* adding name */\r
482   for ( a = 0 ; a < F_MAXNAME ; a++ )\r
483   {\r
484     char  ch = *filename++;\r
485 \r
486     if ( ( !ch ) || ( ch == 32 ) )\r
487     {\r
488       break;\r
489     }\r
490 \r
491     if ( buffersize <= 0 )\r
492     {\r
493       return 1;\r
494     }\r
495 \r
496     *fullname++ = ch;\r
497     buffersize--;\r
498   }\r
499 \r
500   /* adding ext*/\r
501   if ( fileext[0] && ( fileext[0] != 32 ) )\r
502   {\r
503     /* adding dot */\r
504     if ( !buffersize )\r
505     {\r
506       return 1;\r
507     }\r
508 \r
509     *fullname++ = '.';\r
510 \r
511     for ( a = 0 ; a < F_MAXEXT ; a++ )\r
512     {\r
513       char  ch = *fileext++;\r
514 \r
515       if ( ( !ch ) || ( ch == 32 ) )\r
516       {\r
517         break;\r
518       }\r
519 \r
520       if ( buffersize <= 0 )\r
521       {\r
522         return 1;\r
523       }\r
524 \r
525       *fullname++ = ch;\r
526       buffersize--;\r
527     }\r
528   }\r
529 \r
530   /* adding terminator */\r
531   if ( buffersize <= 0 )\r
532   {\r
533     return 1;\r
534   }\r
535 \r
536   *fullname++ = 0;\r
537 \r
538   return 0;\r
539 } /* _f_createfullname */\r
540 \r
541 \r
542 \r