implement directory listing
This commit is contained in:
parent
833a6c5a55
commit
ee8dce893b
77
dump_inode.c
77
dump_inode.c
|
@ -107,7 +107,7 @@ int main(int argc, char **argv) {
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!mode || optind + 1 != argc) {
|
if (!(mode & (MODE_ALL | MODE_INODE)) || optind + 1 != argc) {
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,16 +120,16 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
// find superblock
|
// find superblock
|
||||||
sblock = xmalloc(SBLOCKSIZE);
|
sblock = xmalloc(SBLOCKSIZE);
|
||||||
int sblock_try[] = SBLOCKSEARCH;
|
off_t sblock_try[] = SBLOCKSEARCH;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; sblock_try[i] != -1; i++) {
|
for (i = 0; sblock_try[i] != -1; i++) {
|
||||||
ssize_t n = pread(diskfd, sblock, SBLOCKSIZE, (off_t)sblock_try[i]);
|
xpread(diskfd, sblock, SBLOCKSIZE, sblock_try[i]);
|
||||||
if (n == SBLOCKSIZE &&
|
if ((sblock->fs_magic == FS_UFS1_MAGIC ||
|
||||||
(sblock->fs_magic == FS_UFS1_MAGIC ||
|
|
||||||
(sblock->fs_magic == FS_UFS2_MAGIC &&
|
(sblock->fs_magic == FS_UFS2_MAGIC &&
|
||||||
sblock->fs_sblockloc == sblock_try[i])) &&
|
sblock->fs_sblockloc == sblock_try[i])) &&
|
||||||
sblock->fs_bsize <= MAXBSIZE && sblock->fs_bsize >= sizeof(struct fs))
|
sblock->fs_bsize <= MAXBSIZE && sblock->fs_bsize >= sizeof(struct fs)) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (sblock_try[i] == -1) {
|
if (sblock_try[i] == -1) {
|
||||||
errx(1, "Cannot find filesystem superblock");
|
errx(1, "Cannot find filesystem superblock");
|
||||||
|
@ -233,26 +233,77 @@ void dump_inode(ino_t inum, union dinode *dp) {
|
||||||
DIP(dp, di_mtime), DIP(dp, di_ctime));
|
DIP(dp, di_mtime), DIP(dp, di_ctime));
|
||||||
}
|
}
|
||||||
|
|
||||||
void dump_dirblk(void *dirblk, size_t size) {
|
void dump_dirblk(int deleted, void *dirblk, size_t size) {
|
||||||
struct direct *d = dirblk;
|
char *end = (char *)dirblk + size;
|
||||||
errx(1, "Not implemented");
|
for (struct direct *d = dirblk;
|
||||||
|
(char *)&d->d_name < end && d->d_name + d->d_namlen - 1 < end;
|
||||||
|
d = (struct direct *)((char *)d + d->d_reclen)) {
|
||||||
|
char type;
|
||||||
|
switch (d->d_type) {
|
||||||
|
case DT_FIFO:
|
||||||
|
type = 'p';
|
||||||
|
break;
|
||||||
|
case DT_CHR:
|
||||||
|
type = 'c';
|
||||||
|
break;
|
||||||
|
case DT_DIR:
|
||||||
|
type = 'd';
|
||||||
|
break;
|
||||||
|
case DT_BLK:
|
||||||
|
type = 'b';
|
||||||
|
break;
|
||||||
|
case DT_REG:
|
||||||
|
type = 'f';
|
||||||
|
break;
|
||||||
|
case DT_LNK:
|
||||||
|
type = 'l';
|
||||||
|
break;
|
||||||
|
case DT_SOCK:
|
||||||
|
type = 's';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
type = 'u';
|
||||||
|
}
|
||||||
|
char name[MAXNAMLEN + 1];
|
||||||
|
memcpy(name, d->d_name, d->d_namlen);
|
||||||
|
name[d->d_namlen] = '\0';
|
||||||
|
printf("deleted:%d inode:%" PRIu32 " type:%c name:%s\n", deleted, d->d_ino,
|
||||||
|
type, name);
|
||||||
|
d->d_reclen = MIN(d->d_reclen, end - (char *)d);
|
||||||
|
d->d_reclen &= ~3;
|
||||||
|
if (!d->d_reclen) {
|
||||||
|
if (!deleted) {
|
||||||
|
warnx("Corrupted directory entry");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (d->d_reclen > DIRSIZ(NEWDIRFMT, d)) {
|
||||||
|
dump_dirblk(1, (char *)d + DIRSIZ(NEWDIRFMT, d),
|
||||||
|
d->d_reclen - DIRSIZ(NEWDIRFMT, d));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dump_directory(union dinode *dp) {
|
void dump_directory(union dinode *dp) {
|
||||||
if ((DIP(dp, di_mode) & IFMT) != IFDIR) {
|
if ((DIP(dp, di_mode) & IFMT) != IFDIR) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void *datablock = xmalloc(sblock->fs_bsize);
|
char *datablock = xmalloc(sblock->fs_bsize);
|
||||||
off_t filesize = DIP(dp, di_size);
|
off_t filesize = DIP(dp, di_size);
|
||||||
for (int i = 0; filesize > 0 && i < NDADDR; i++) {
|
for (int i = 0; filesize > 0 && i < NDADDR;
|
||||||
filesize -= sblock->fs_bsize;
|
filesize -= sblock->fs_bsize, i++) {
|
||||||
if (!DIP(dp, di_db[i])) {
|
if (!DIP(dp, di_db[i])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
size_t blksize = sblksize(sblock, DIP(dp, di_size), i);
|
size_t blksize = sblksize(sblock, DIP(dp, di_size), i);
|
||||||
daddr_t blkno = fsbtodb(sblock, DIP(dp, di_db[i]));
|
daddr_t blkno = fsbtodb(sblock, DIP(dp, di_db[i]));
|
||||||
xpread(diskfd, datablock, blksize, blkno * DEV_BSIZE);
|
xpread(diskfd, datablock, blksize, blkno * DEV_BSIZE);
|
||||||
dump_dirblk(datablock, blksize);
|
if (filesize < blksize) {
|
||||||
|
blksize = filesize;
|
||||||
|
}
|
||||||
|
for (size_t j = 0; j < blksize; j += DIRBLKSIZ) {
|
||||||
|
dump_dirblk(0, datablock + j, MIN(blksize - j, DIRBLKSIZ));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (filesize > 0) {
|
if (filesize > 0) {
|
||||||
errx(1, "Indirect blocks not implemented");
|
errx(1, "Indirect blocks not implemented");
|
||||||
|
|
Loading…
Reference in a new issue