summaryrefslogtreecommitdiffstats
path: root/lib/libstand/dosfs.c
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2013-12-18 04:44:38 +0000
committermarcel <marcel@FreeBSD.org>2013-12-18 04:44:38 +0000
commit9ca55833b64341e1f2e98b057767806ce3483918 (patch)
tree523afabd034e909448619c07b8b05be0484df366 /lib/libstand/dosfs.c
parent226d58924f94628272fd944d1bbf2781f70f37f9 (diff)
downloadFreeBSD-src-9ca55833b64341e1f2e98b057767806ce3483918.zip
FreeBSD-src-9ca55833b64341e1f2e98b057767806ce3483918.tar.gz
Support long filenames.
Obtained from: Juniper Networks, Inc.
Diffstat (limited to 'lib/libstand/dosfs.c')
-rw-r--r--lib/libstand/dosfs.c37
1 files changed, 24 insertions, 13 deletions
diff --git a/lib/libstand/dosfs.c b/lib/libstand/dosfs.c
index e15ecdc..f43b721 100644
--- a/lib/libstand/dosfs.c
+++ b/lib/libstand/dosfs.c
@@ -381,21 +381,32 @@ dos_readdir(struct open_file *fd, struct dirent *d)
if (dd.de.name[0] == 0xe5)
continue;
- /* Skip volume labels */
- if (dd.de.attr & FA_LABEL)
- continue;
-
- if ((dd.de.attr & FA_MASK) == FA_XDE) {
- if (dd.xde.seq & 0x40)
- chk = dd.xde.chk;
- else if (dd.xde.seq != xdn - 1 || dd.xde.chk != chk)
- continue;
- x = dd.xde.seq & ~0x40;
- if (x < 1 || x > 20) {
- x = 0;
+ /* Check if directory entry is volume label */
+ if (dd.de.attr & FA_LABEL) {
+ /*
+ * If volume label set, check if the current entry is
+ * extended entry (FA_XDE) for long file names.
+ */
+ if ((dd.de.attr & FA_MASK) == FA_XDE) {
+ /*
+ * Read through all following extended entries
+ * to get the long file name. 0x40 marks the
+ * last entry containing part of long file name.
+ */
+ if (dd.xde.seq & 0x40)
+ chk = dd.xde.chk;
+ else if (dd.xde.seq != xdn - 1 || dd.xde.chk != chk)
+ continue;
+ x = dd.xde.seq & ~0x40;
+ if (x < 1 || x > 20) {
+ x = 0;
+ continue;
+ }
+ cp_xdnm(fn, &dd.xde);
+ } else {
+ /* skip only volume label entries */
continue;
}
- cp_xdnm(fn, &dd.xde);
} else {
if (xdn == 1) {
x = 0;
OpenPOWER on IntegriCloud