MFC rev 201937:
Implement the fo_readdir method.
This commit is contained in:
parent
4f6e5678b5
commit
4780cb8a56
@ -47,6 +47,7 @@ static int dos_close(struct open_file *fd);
|
||||
static int dos_read(struct open_file *fd, void *buf, size_t size, size_t *resid);
|
||||
static off_t dos_seek(struct open_file *fd, off_t offset, int whence);
|
||||
static int dos_stat(struct open_file *fd, struct stat *sb);
|
||||
static int dos_readdir(struct open_file *fd, struct dirent *d);
|
||||
|
||||
struct fs_ops dosfs_fsops = {
|
||||
"dosfs",
|
||||
@ -56,7 +57,7 @@ struct fs_ops dosfs_fsops = {
|
||||
null_write,
|
||||
dos_seek,
|
||||
dos_stat,
|
||||
null_readdir
|
||||
dos_readdir
|
||||
};
|
||||
|
||||
#define SECSIZ 512 /* sector size */
|
||||
@ -354,6 +355,72 @@ dos_stat(struct open_file *fd, struct stat *sb)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
dos_readdir(struct open_file *fd, struct dirent *d)
|
||||
{
|
||||
DOS_FILE *f = (DOS_FILE *)fd->f_fsdata;
|
||||
u_char fn[261];
|
||||
DOS_DIR dd;
|
||||
size_t res;
|
||||
u_int chk, i, x, xdn;
|
||||
int err;
|
||||
|
||||
x = chk = 0;
|
||||
while (1) {
|
||||
xdn = x;
|
||||
x = 0;
|
||||
err = dos_read(fd, &dd, sizeof(dd), &res);
|
||||
if (err)
|
||||
return (err);
|
||||
if (res == sizeof(dd))
|
||||
return (ENOENT);
|
||||
if (dd.de.name[0] == 0)
|
||||
return (ENOENT);
|
||||
|
||||
/* Skip deleted entries */
|
||||
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;
|
||||
continue;
|
||||
}
|
||||
cp_xdnm(fn, &dd.xde);
|
||||
} else {
|
||||
if (xdn == 1) {
|
||||
x = 0;
|
||||
for (i = 0; i < 11; i++) {
|
||||
x = ((x & 1) << 7) | (x >> 1);
|
||||
x += dd.de.name[i];
|
||||
x &= 0xff;
|
||||
}
|
||||
if (x == chk)
|
||||
break;
|
||||
} else {
|
||||
cp_sfn(fn, &dd.de);
|
||||
break;
|
||||
}
|
||||
x = 0;
|
||||
}
|
||||
}
|
||||
|
||||
d->d_fileno = dd.de.clus[1] << 8 + dd.de.clus[0];
|
||||
d->d_reclen = sizeof(*d);
|
||||
d->d_type = (dd.de.attr & FA_DIR) ? DT_DIR : DT_REG;
|
||||
memcpy(d->d_name, fn, sizeof(d->d_name));
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse DOS boot sector
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user