summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-07-13 17:19:31 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-07-13 17:19:31 +0000
commit7aabcf55a461014d7a81136c51e96c2c62faffd3 (patch)
tree832981f8c7aa56842ceb5f662f555227d9c986d0
parentedeffa28c526825510f7ff35024ea242f82252e5 (diff)
downloadnuttx-7aabcf55a461014d7a81136c51e96c2c62faffd3.tar.gz
nuttx-7aabcf55a461014d7a81136c51e96c2c62faffd3.tar.bz2
nuttx-7aabcf55a461014d7a81136c51e96c2c62faffd3.zip
Add long file name parsing logic
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3781 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--nuttx/Documentation/NuttxPortingGuide.html15
-rw-r--r--nuttx/configs/README.txt11
-rw-r--r--nuttx/fs/fat/fs_fat32.h4
-rw-r--r--nuttx/fs/fat/fs_fat32dirent.c692
4 files changed, 615 insertions, 107 deletions
diff --git a/nuttx/Documentation/NuttxPortingGuide.html b/nuttx/Documentation/NuttxPortingGuide.html
index 4e5991001..8d6a3544c 100644
--- a/nuttx/Documentation/NuttxPortingGuide.html
+++ b/nuttx/Documentation/NuttxPortingGuide.html
@@ -12,7 +12,7 @@
<h1><big><font color="#3c34ec">
<i>NuttX RTOS Porting Guide</i>
</font></big></h1>
- <p>Last Updated: July 12, 2011</p>
+ <p>Last Updated: July 13, 2011</p>
</td>
</tr>
</table>
@@ -3764,6 +3764,19 @@ build
<code>CONFIG_FAT_SECTORSIZE</code>: Max supported sector size.
</li>
<li>
+ <code>CONFIG_FAT_LCNAME</code>: Enable use of the NT-style upper/lower case 8.3 file name support.
+ </li>
+ <li>
+ <code>CONFIG_FAT_LFN</code>: Enable FAT long file names.
+ NOTE: Microsoft claims patents on FAT long file name technology.
+ Please read the disclaimer in the top-level COPYING file and only enable this feature if you understand these issues.
+ </li>
+ <li>
+ <code>CONFIG_FAT_MAXFNAME</code>: If <code>CONFIG_FAT_LFN</code> is defined, then the default, maximum long file name is 255 bytes.
+ This can eat up a lot of memory (especially stack space).
+ If you are willing to live with some non-standard, short long file names, then define this value.
+ </li>
+ <li>
<code>CONFIG_FS_NXFFS</code>: Enable NuttX FLASH file system (NXFF) support.
</li>
<li>
diff --git a/nuttx/configs/README.txt b/nuttx/configs/README.txt
index a2c012931..f505685f2 100644
--- a/nuttx/configs/README.txt
+++ b/nuttx/configs/README.txt
@@ -564,6 +564,17 @@ defconfig -- This is a configuration file similar to the Linux
Filesystem configuration
CONFIG_FS_FAT - Enable FAT filesystem support
CONFIG_FAT_SECTORSIZE - Max supported sector size
+ CONFIG_FAT_LCNAME - Enable use of the NT-style upper/lower case 8.3
+ file name support.
+ CONFIG_FAT_LFN - Enable FAT long file names. NOTE: Microsoft claims
+ patents on FAT long file name technology. Please read the
+ disclaimer in the top-level COPYING file and only enable this
+ feature if you understand these issues.
+ CONFIG_FAT_MAXFNAME - If CONFIG_FAT_LFN is defined, then the
+ default, maximum long file name is 255 bytes. This can eat up
+ a lot of memory (especially stack space). If you are willing
+ to live with some non-standard, short long file names, then
+ define this value.
CONFIG_FS_NXFFS: Enable NuttX FLASH file system (NXFF) support.
CONFIG_NXFFS_ERASEDSTATE: The erased state of FLASH.
This must have one of the values of 0xff or 0x00.
diff --git a/nuttx/fs/fat/fs_fat32.h b/nuttx/fs/fat/fs_fat32.h
index 3d3db644c..5c10de000 100644
--- a/nuttx/fs/fat/fs_fat32.h
+++ b/nuttx/fs/fat/fs_fat32.h
@@ -732,9 +732,9 @@ struct fat_dirinfo_s
/* The file/directory name */
#ifdef CONFIG_FAT_LFN
- uint8_t fd_lfname[LDIR_MAXFNAME]; /* Long filename */
+ uint8_t fd_lfname[LDIR_MAXFNAME+1]; /* Long filename with terminator */
#endif
- uint8_t fd_name[DIR_MAXFNAME]; /* Short 8.3 alias filename */
+ uint8_t fd_name[DIR_MAXFNAME]; /* Short 8.3 alias filename (no terminator) */
/* NT flags are not used */
diff --git a/nuttx/fs/fat/fs_fat32dirent.c b/nuttx/fs/fat/fs_fat32dirent.c
index f98d75a9d..8703ae47a 100644
--- a/nuttx/fs/fat/fs_fat32dirent.c
+++ b/nuttx/fs/fat/fs_fat32dirent.c
@@ -94,6 +94,13 @@
* Private Types
****************************************************************************/
+enum fat_case_e
+{
+ FATCASE_UNKNOWN = 0,
+ FATCASE_UPPER,
+ FATCASE_LOWER
+};
+
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
@@ -111,19 +118,21 @@
****************************************************************************/
/****************************************************************************
- * Name: fat_path2dirname
+ * Name: fat_parsesfname
*
* Desciption: Convert a user filename into a properly formatted FAT
- * (short) filname as it would appear in a directory entry. Here are the
- * rules for the 11 byte name in the directory:
+ * (short 8.3) filename as it would appear in a directory entry. Here are
+ * the rules for the 8+3 short file name in the directory:
*
* The first byte:
- * - 0xe5 = The directory is free
- * - 0x00 = This directory and all following directories are free
- * - 0x05 = Really 0xe5
- * - 0x20 = May NOT be ' '
*
- * Any bytes
+ * 0xe5 = The directory is free
+ * 0x00 = This directory and all following directories are free
+ * 0x05 = Really 0xe5
+ * 0x20 = May NOT be ' '
+ *
+ * Other characters may be any characters except for the following:
+ *
* 0x00-0x1f = (except for 0x00 and 0x05 in the first byte)
* 0x22 = '"'
* 0x2a-0x2c = '*', '+', ','
@@ -132,152 +141,627 @@
* 0x5b-0x5d = '[', '\\', ;]'
* 0x7c = '|'
*
- * Upper case characters are not allowed in directory names (without some
- * poorly documented operatgions on the NTRes directory byte). Lower case
+ * '.' May only occur once within string and only within the first 9
+ * bytes. The '.' is not save in the directory, but is implicit in
+ * 8+3 format.
+ *
+ * Lower case characters are not allowed in directory names (without some
+ * poorly documented operations on the NTRes directory byte). Lower case
* codes may represent different characters in other character sets ("DOS
* code pages". The logic below does not, at present, support any other
* character sets.
*
+ * Returned value:
+ * OK - The path refers to a valid 8.3 FAT file name and has been properly
+ * converted and stored in dirinfo.
+ * <0 - Otherwise an negated error is returned meaning that the string is
+ * not a valid 8+3 because:
+ *
+ * 1. Contains characters not in the printable character set,
+ * 2. Contains forbidden characters or multiple '.' characters
+ * 3. File name or extension is too long.
+ *
+ * If CONFIG_FAT_LFN is defined and CONFIG_FAT_LCNAMES is NOT
+ * defined, then:
+ *
+ * 4a. File name or extension contains lower case characters.
+ *
+ * If CONFIG_FAT_LFN is defined and CONFIG_FAT_LCNAMES is defined,
+ * then:
+ *
+ * 4b. File name or extension is not all the same case.
+ *
****************************************************************************/
-static inline int fat_path2dirname(const char **path, struct fat_dirinfo_s *dirinfo,
+static inline int fat_parsesfname(const char **path,
+ struct fat_dirinfo_s *dirinfo,
char *terminator)
{
#ifdef CONFIG_FAT_LCNAMES
- unsigned int ntlcenable = FATNTRES_LCNAME | FATNTRES_LCEXT;
- unsigned int ntlcfound = 0;
+ unsigned int ntlcenable = FATNTRES_LCNAME | FATNTRES_LCEXT;
+ unsigned int ntlcfound = 0;
+#ifdef CONFIG_FAT_LFN
+ enum fat_case_e namecase = FATCASE_UNKNOWN;
+ enum fat_case_e extcase = FATCASE_UNKNOWN;
#endif
- const char *node = *path;
- int endndx;
- uint8_t ch;
- int ndx = 0;
+#endif
+ const char *node = *path;
+ int endndx;
+ uint8_t ch;
+ int ndx = 0;
- /* Initialized the name with all spaces */
+ /* Initialized the name with all spaces */
- memset(dirinfo->fd_name, ' ', DIR_MAXFNAME);
+ memset(dirinfo->fd_name, ' ', DIR_MAXFNAME);
- /* Loop until the name is successfully parsed or an error occurs */
+ /* Loop until the name is successfully parsed or an error occurs */
- endndx = 8;
- for (;;)
- {
- /* Get the next byte from the path */
+ endndx = 8;
+ for (;;)
+ {
+ /* Get the next byte from the path */
- ch = *node++;
+ ch = *node++;
- /* Check if this the last byte in this node of the name */
+ /* Check if this the last byte in this node of the name */
+
+ if ((ch == '\0' || ch == '/') && ndx != 0 )
+ {
+ /* Return the accumulated NT flags and the terminating character */
- if ((ch == '\0' || ch == '/') && ndx != 0 )
- {
- /* Return the accumulated NT flags and the terminating character */
#ifdef CONFIG_FAT_LCNAMES
- dirinfo->fd_ntflags = ntlcfound & ntlcenable;
+ dirinfo->fd_ntflags = ntlcfound & ntlcenable;
#endif
- *terminator = ch;
- *path = node;
- return OK;
- }
+ *terminator = ch;
+ *path = node;
+ return OK;
+ }
- /* Accept only the printable character set. Note the first byte
- * of the name could be 0x05 meaning that is it 0xe5, but this is
- * not a printable character in this character in either case.
- */
+ /* Accept only the printable character set. Note the first byte
+ * of the name could be 0x05 meaning that is it 0xe5, but this is
+ * not a printable character in this character in either case.
+ */
- else if (!isgraph(ch))
- {
- goto errout;
- }
+ else if (!isgraph(ch))
+ {
+ goto errout;
+ }
- /* Check for transition from name to extension */
+ /* Check for transition from name to extension. Only one '.' is
+ * permitted and it must be within first 9 characters
+ */
- else if (ch == '.')
- {
- /* Starting the extension */
+ else if (ch == '.' && endndx == 8)
+ {
+ /* Starting the extension */
- ndx = 8;
- endndx = 11;
- continue;
- }
+ ndx = 8;
+ endndx = 11;
+ continue;
+ }
- /* Reject printable characters forbidden by FAT */
+ /* Reject printable characters forbidden by FAT */
- else if (ch == '"' || (ch >= '*' && ch <= ',') ||
- ch == '.' || ch == '/' ||
- (ch >= ':' && ch <= '?') ||
- (ch >= '[' && ch <= ']') ||
- (ch == '|'))
- {
- goto errout;
- }
+ else if (ch == '"' || (ch >= '*' && ch <= ',') ||
+ ch == '.' || ch == '/' ||
+ (ch >= ':' && ch <= '?') ||
+ (ch >= '[' && ch <= ']') ||
+ (ch == '|'))
+ {
+ goto errout;
+ }
- /* Check for upper case charaters */
+ /* Check for upper case characters */
#ifdef CONFIG_FAT_LCNAMES
- else if (isupper(ch))
- {
- /* Some or all of the characters in the name or extension
- * are upper case. Force all of the characters to be interpreted
- * as upper case.
- */
+ else if (isupper(ch))
+ {
+ /* Some or all of the characters in the name or extension
+ * are upper case. Force all of the characters to be interpreted
+ * as upper case.
+ */
- if ( endndx == 8)
+ if (endndx == 8)
+ {
+ /* Is there mixed case in the name? */
+
+#ifdef CONFIG_FAT_LFN
+ if (namecase == FATCASE_LOWER)
{
- /* Clear lower case name bit in mask*/
- ntlcenable &= FATNTRES_LCNAME;
+ /* Mixed case in the name -- use the long file name */
+
+ goto errout;
}
- else
+
+ /* So far, only upper case in the name*/
+
+ namecase = FATCASE_UPPER;
+#endif
+
+ /* Clear lower case name bit in mask*/
+
+ ntlcenable &= FATNTRES_LCNAME;
+ }
+ else
+ {
+ /* Is there mixed case in the extension? */
+
+#ifdef CONFIG_FAT_LFN
+ if (extcase == FATCASE_LOWER)
{
- /* Clear lower case extension in mask */
- ntlcenable &= FATNTRES_LCNAME;
+ /* Mixed case in the extension -- use the long file name */
+
+ goto errout;
}
- }
+
+ /* So far, only upper case in the extension*/
+
+ extcase = FATCASE_UPPER;
#endif
- /* Check for lower case characters */
+ /* Clear lower case extension in mask */
- else if (islower(ch))
- {
- /* Convert the character to upper case */
+ ntlcenable &= FATNTRES_LCNAME;
+ }
+ }
+#endif
- ch = toupper(ch);
+ /* Check for lower case characters */
- /* Some or all of the characters in the name or extension
- * are lower case. They can be interpreted as lower case if
- * only if all of the characters in the name or extension are
- * lower case.
- */
+ else if (islower(ch))
+ {
+#if defined(CONFIG_FAT_LFN) && !defined(CONFIG_FAT_LCNAMES)
+ /* If lower case characters are present, then a long file
+ * name will be constructed.
+ */
+
+ goto errout;
+#else
+ /* Convert the character to upper case */
+
+ ch = toupper(ch);
+
+ /* Some or all of the characters in the name or extension
+ * are lower case. They can be interpreted as lower case if
+ * only if all of the characters in the name or extension are
+ * lower case.
+ */
#ifdef CONFIG_FAT_LCNAMES
- if ( endndx == 8)
- {
- /* Set lower case name bit */
- ntlcfound |= FATNTRES_LCNAME;
- }
- else
- {
- /* Set lower case extension bit */
- ntlcfound |= FATNTRES_LCNAME;
- }
+ if (endndx == 8)
+ {
+ /* Is there mixed case in the name? */
+
+#ifdef CONFIG_FAT_LFN
+ if (namecase == FATCASE_UPPER)
+ {
+ /* Mixed case in the name -- use the long file name */
+
+ goto errout;
+ }
+
+ /* So far, only lower case in the name*/
+
+ namecase = FATCASE_LOWER;
#endif
- }
- /* Check if the file name exceeds the size permitted (without
- * long file name support
- */
+ /* Set lower case name bit */
- if (ndx >= endndx)
- {
- goto errout;
- }
+ ntlcfound |= FATNTRES_LCNAME;
+ }
+ else
+ {
+ /* Is there mixed case in the extension? */
- /* Save next character in the accumulated name */
+#ifdef CONFIG_FAT_LFN
+ if (extcase == FATCASE_UPPER)
+ {
+ /* Mixed case in the extension -- use the long file name */
- dirinfo->fd_name[ndx++] = ch;
- }
+ goto errout;
+ }
+
+ /* So far, only lower case in the extension*/
+
+ extcase = FATCASE_LOWER;
+#endif
+
+ /* Set lower case extension bit */
+
+ ntlcfound |= FATNTRES_LCNAME;
+ }
+#endif
+#endif /* CONFIG_FAT_LFN && !CONFIG_FAT_LCNAMES */
+ }
+
+ /* Check if the file name exceeds the size permitted (without
+ * long file name support).
+ */
+
+ if (ndx >= endndx)
+ {
+ goto errout;
+ }
+
+ /* Save next character in the accumulated name */
+
+ dirinfo->fd_name[ndx++] = ch;
+ }
errout:
+ return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: fat_parselfname
+ *
+ * Desciption: Convert a user filename into a properly formatted FAT
+ * long filename as it would appear in a directory entry. Here are
+ * the rules for the long file name in the directory:
+ *
+ * Valid characters are the same as for short file names EXCEPT:
+ *
+ * 1. '+', ',', ';', '=', '[', and ']' are accepted in the file name
+ * 2. '.' (dot) can occur more than once in a filename. Extension is
+ * the substring after the last dot.
+ *
+ * Returned value:
+ * OK - The path refers to a valid long file name and has been properly
+ * stored in dirinfo.
+ * <0 - Otherwise an negated error is returned meaning that the string is
+ * not a valid long file name:
+ *
+ * 1. Contains characters not in the printable character set,
+ * 2. Contains forbidden characters
+ * 3. File name is too long.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_FAT_LFN
+static inline int fat_parselfname(const char **path,
+ struct fat_dirinfo_s *dirinfo,
+ char *terminator)
+{
+ const char *node = *path;
+ uint8_t ch;
+ int ndx = 0;
+
+ /* Loop until the name is successfully parsed or an error occurs */
+
+ for (;;)
+ {
+ /* Get the next byte from the path */
+
+ ch = *node++;
+
+ /* Check if this the last byte in this node of the name */
+
+ if ((ch == '\0' || ch == '/') && ndx != 0 )
+ {
+ /* Null terminate the string */
+
+ dirinfo->fd_lfname[ndx] = '\0';
+
+ /* Return the remaining sub-string and the terminating character. */
+
+ *terminator = ch;
+ *path = node;
+ return OK;
+ }
+
+ /* Accept only the printable character set */
+
+ else if (!isgraph(ch))
+ {
+ goto errout;
+ }
+
+ /* Reject printable characters forbidden by FAT */
+
+ else if (ch == '"' || ch == '*' || ch == '/' || ch == ':' ||
+ ch == '<' || ch == '>' || ch == '?' || ch == '\\' ||
+ ch == '|')
+ {
+ goto errout;
+ }
+
+ /* Check if the file name exceeds the size permitted. */
+
+ if (ndx >= LDIR_MAXFNAME)
+ {
+ goto errout;
+ }
+
+ /* Save next character in the accumulated name */
+
+ dirinfo->fd_lfname[ndx++] = ch;
+ }
+
+ errout:
+ dirinfo->fd_lfname[0] = '\0';
return -EINVAL;
}
+#endif
+
+/****************************************************************************
+ * Name: fat_createalias
+ *
+ * Desciption: Given a valid long file name, create a short filename alias.
+ * Here are the rules for creation of the alias:
+ *
+ * 1. All uppercase
+ * 2. All dots except the last deleted
+ * 3. First 6 (uppercase) characters used as a base
+ * 4. Then ~1. The number is increased if the file already exists in the
+ * directory. If the number exeeds >10, then character stripped off the
+ * base.
+ * 5. The extension is the first 3 uppercase chars of extension.
+ *
+ * Returned value:
+ * OK - The alias was created correctly.
+ * <0 - Otherwise an negated error is returned.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_FAT_LFN
+static inline int fat_createalias(const char **path,
+ struct fat_dirinfo_s *dirinfo)
+{
+ uint8_t ch; /* Current character being processed */
+ char *ext; /* Pointer to the extension substring */
+ char *ptr; /* Working pointer */
+ int len; /* Total length of the long file name */
+ int namechars; /* Number of characters available in long name */
+ int extchars; /* Number of characters available in long name extension */
+ int endndx; /* Maximum index into the short name array */
+ int ndx; /* Index to store next character */
+
+ /* First, let's decide what is name and what is extension */
+
+ len = strlen(dirinfo.fd_lfname);
+ ext = strrchr(dirinfo.fd_lfname, '.');
+ if (ext)
+ {
+ ptrdiff_t tmp;
+
+ /* ext points to the final '.'. The difference in bytes from the
+ * beginning of the string is then the name length.
+ */
+
+ tmp = ext - dirinfo.fd_lfname;
+ namechars = tmp;
+
+ /* And the rest, exluding the '.' is the extension. */
+
+ extchars = len - namechars - 1;
+ ext++;
+ }
+ else
+ {
+ /* No '.' found. It is all name and no extension. */
+
+ namechars = len;
+ extchars = 0;
+ }
+
+ /* Alias are always all upper case */
+
+#ifdef CONFIG_FAT_LCNAMES
+ dirinfo->fd_ntflags = 0;
+#endif
+
+ /* Initialized the short name with all spaces */
+
+ memset(dirinfo->fd_name, ' ', DIR_MAXFNAME);
+
+ /* Handle a special case where there is no name. Windows seems to use
+ * the extension plus random stuff then ~1 to pat to 8 bytes. Some
+ * examples:
+ *
+ * a.b -> a.b No long name
+ * a., -> A26BE~1._ Padded name to make unique, _ replaces ,
+ * .b -> B1DD2~1 Extension used as name
+ * .bbbbbbb -> BBBBBB~1 Extension used as name
+ * a.bbbbbbb -> AAD39~1.BBB Padded name to make unique.
+ * aaa.bbbbbbb -> AAA~1.BBBB Not padded, already unique?
+ * ,.bbbbbbb -> _82AF~1.BBB _ replaces ,
+ * +[],.bbbbbbb -> ____~1.BBB _ replaces +[],
+ */
+
+ if (namechars < 1)
+ {
+ /* Use the extension as the name */
+
+ DEBUGASSERT(ext && extchars > 0);
+ ptr = ext;
+ ext = NULL;
+ namechar = extchars;
+ extchars = 0;
+ }
+ else
+ {
+ ptr = dirinfo.fd_ldname;
+ }
+
+ /* Then copy the name and extension, handling upper case conversions and
+ * excluding forbidden characters.
+ */
+
+ ndx = 0; /* Position to write the next name character */
+ endndx = 6; /* Maximum index before we write ~! and switch to the extension */
+
+ for (;;)
+ {
+ /* Get the next byte from the path. Break out of the loop if we
+ * encounter the end of null-terminated the long file name string.
+ */
+
+ ch = *ptr++;
+ if (ch == '\0')
+ {
+ break;
+ }
+
+ /* Exclude those few characters included in long file names, but
+ * excluded in short file name: '+', ',', ';', '=', '[', ']', and '.'
+ */
+
+ if (ch == '+' || ch == ',' || ch == '.' || ch == ';' ||
+ ch == '=' || ch == '[' || ch == ']' || ch == '|')
+ {
+ /* Use the underbar character instead */
+
+ ch = '_';
+ }
+
+ /* Handle lower case characters */
+
+ ch = toupper(ch);
+
+ /* We now have a valid character to add to the name or extension. */
+
+ dirinfo->fd_name[ndx++] = ch;
+
+ /* Did we just add a character to the name? */
+
+ if (endndx == 6)
+ {
+ /* Decrement the number of characters available in the name
+ * portion of the long name.
+ */
+
+ namechars--;
+
+ /* Is it time to add ~1 to the string? Will will do that if
+ * either (1) we have already added the maximum number of
+ * characters to the short name, or (2) if there are no further
+ * characters available in the name portion of the long name.
+ */
+
+ if (namechars < 1 || ndx == 6)
+ {
+ /* Write the ~1 at the end of the name */
+
+ dirinfo->fd_name[ndx++] = '~';
+ dirinfo->fd_name[ndx++] = '1';
+
+ /* Then switch to the extension (if there is one) */
+
+ if (!ext || extchars < 1)
+ {
+ return OK;
+ }
+
+ ndx = 8;
+ endndx = 11;
+ ptr = ext;
+ }
+ }
+
+ /* No.. we just added a character to the extension */
+
+ else
+ {
+ /* Decrement the number of characters available in the name
+ * portion of the long name
+ */
+
+ extchars--;
+
+ /* Is the extension complete? */
+
+ if (extchars < 1 || ndx == 11)
+ {
+ return OK;
+ }
+ }
+ }
+}
+#endif
+
+/****************************************************************************
+ * Name: fat_uniquealias
+ *
+ * Desciption: Make sure that the short alias for the long file name is
+ * unique. Modify the alias as necessary to assure uniqueness.
+ *
+ * Returned value:
+ * OK - The alias is unique.
+ * <0 - Otherwise an negated error is returned.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_FAT_LFN
+static inline int fat_uniquealias(const char **path,
+ struct fat_dirinfo_s *dirinfo)
+{
+#warning "Missing alias alias uniqueness logic"
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: fat_path2dirname
+ *
+ * Desciption: Convert a user filename into a properly formatted FAT
+ * (short 8.3) filename as it would appear in a directory entry.
+ *
+ ****************************************************************************/
+
+static int fat_path2dirname(const char **path, struct fat_dirinfo_s *dirinfo,
+ char *terminator)
+{
+#ifdef CONFIG_FAT_LFN
+ int ret;
+
+ /* Assume no long file name */
+
+ dirinfo->fd_lfname[0] = '\0';
+
+ /* Then parse the (assumed) 8+3 short file name */
+
+ ret = fat_parsesfname(path, dirinfo, terminator);
+ if (ret < 0)
+ {
+ /* No, the name is not a valid short 8+3 file name. Try parsing
+ * the long file name.
+ */
+
+ ret = fat_parselfname(path, dirinfo, terminator);
+ if (ret < 0)
+ {
+ /* Not a valid long file name */
+
+ return ret;
+ }
+
+ /* It is a valid long file name, create a quick short file name
+ * alias.
+ */
+
+ ret = fat_createalias(path, dirinfo);
+ DEBUGASSERT(ret == OK); /* This should never fail */
+
+ /* Make sure that the alias is unique */
+
+ ret = fat_uniquealias(path, dirinfo);
+ }
+
+ return ret;
+#else
+ /* Only short, 8+3 filenames supported */
+
+ return fat_parsesfname(path, dirinfo, terminator);
+#endif
+}
+
+/****************************************************************************
+ * Name: fat_checkname
+ *
+ * Desciption: Given a path to something that may or may not be in the file
+ * system, return the directory entry of the item.
+ *
+ ****************************************************************************/
/****************************************************************************
* Public Functions