diff options
author | marcel <marcel@FreeBSD.org> | 2013-12-18 04:44:38 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2013-12-18 04:44:38 +0000 |
commit | 9ca55833b64341e1f2e98b057767806ce3483918 (patch) | |
tree | 523afabd034e909448619c07b8b05be0484df366 /lib/libstand/dosfs.c | |
parent | 226d58924f94628272fd944d1bbf2781f70f37f9 (diff) | |
download | FreeBSD-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.c | 37 |
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; |