static char version
[] = "@(#)pass2.c 3.1 (Berkeley) %G%";
bzero((char *)&rootdesc
, sizeof(struct inodesc
));
rootdesc
.id_func
= pass2check
;
rootdesc
.id_number
= ROOTINO
;
switch (statemap
[ROOTINO
]) {
errexit("ROOT INODE UNALLOCATED. TERMINATING.\n");
pfatal("ROOT INODE NOT DIRECTORY");
if (reply("FIX") == 0 || (dp
= ginode(ROOTINO
)) == NULL
)
statemap
[ROOTINO
] = DSTATE
;
descend(&rootdesc
, ROOTINO
);
pfatal("DUPS/BAD IN ROOT INODE");
if (reply("CONTINUE") == 0)
statemap
[ROOTINO
] = DSTATE
;
descend(&rootdesc
, ROOTINO
);
register DIRECT
*dirp
= idesc
->id_dirp
;
int n
, entrysize
, ret
= 0;
if (idesc
->id_entryno
!= 0)
if (dirp
->d_ino
!= 0 && strcmp(dirp
->d_name
, ".") == 0) {
if (dirp
->d_ino
!= idesc
->id_number
) {
direrr(idesc
->id_number
, "BAD INODE NUMBER FOR '.'");
dirp
->d_ino
= idesc
->id_number
;
direrr(idesc
->id_number
, "MISSING '.'");
proto
.d_ino
= idesc
->id_number
;
(void)strcpy(proto
.d_name
, ".");
entrysize
= DIRSIZ(&proto
);
if (dirp
->d_ino
!= 0 && strcmp(dirp
->d_name
, "..") != 0) {
pfatal("CANNOT FIX, FIRST ENTRY IN DIRECTORY CONTAINS %s\n",
} else if (dirp
->d_reclen
< entrysize
) {
pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '.'\n");
} else if (dirp
->d_reclen
< 2 * entrysize
) {
proto
.d_reclen
= dirp
->d_reclen
;
bcopy((char *)&proto
, (char *)dirp
, entrysize
);
n
= dirp
->d_reclen
- entrysize
;
proto
.d_reclen
= entrysize
;
bcopy((char *)&proto
, (char *)dirp
, entrysize
);
dirp
= (DIRECT
*)((char *)(dirp
) + entrysize
);
if (idesc
->id_entryno
> 1)
proto
.d_ino
= idesc
->id_parent
;
(void)strcpy(proto
.d_name
, "..");
entrysize
= DIRSIZ(&proto
);
if (idesc
->id_entryno
== 0) {
if (dirp
->d_reclen
< n
+ entrysize
)
proto
.d_reclen
= dirp
->d_reclen
- n
;
dirp
= (DIRECT
*)((char *)(dirp
) + n
);
if (dirp
->d_ino
!= 0 && strcmp(dirp
->d_name
, "..") == 0) {
if (dirp
->d_ino
!= idesc
->id_parent
) {
direrr(idesc
->id_number
, "BAD INODE NUMBER FOR '..'");
dirp
->d_ino
= idesc
->id_parent
;
direrr(idesc
->id_number
, "MISSING '..'");
if (dirp
->d_ino
!= 0 && strcmp(dirp
->d_name
, ".") != 0) {
pfatal("CANNOT FIX, SECOND ENTRY IN DIRECTORY CONTAINS %s\n",
} else if (dirp
->d_reclen
< entrysize
) {
pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '..'\n");
proto
.d_reclen
= dirp
->d_reclen
;
bcopy((char *)&proto
, (char *)dirp
, entrysize
);
if (dirp
->d_namlen
<= 2 &&
dirp
->d_name
[0] == '.' &&
idesc
->id_entryno
>= 2) {
if (dirp
->d_namlen
== 1) {
direrr(idesc
->id_number
, "EXTRA '.' ENTRY");
if (dirp
->d_name
[1] == '.') {
direrr(idesc
->id_number
, "EXTRA '..' ENTRY");
if (pathp
+ dirp
->d_namlen
>= endpathname
) {
errexit("NAME TOO LONG %s%s\n", pathname
, dirp
->d_name
);
bcopy(dirp
->d_name
, pathp
, dirp
->d_namlen
+ 1);
if (dirp
->d_ino
> imax
|| dirp
->d_ino
<= 0) {
direrr(dirp
->d_ino
, "I OUT OF RANGE");
switch (statemap
[dirp
->d_ino
]) {
direrr(dirp
->d_ino
, "UNALLOCATED");
direrr(dirp
->d_ino
, "DUP/BAD");
if ((n
= reply("REMOVE")) == 1)
if ((dp
= ginode(dirp
->d_ino
)) == NULL
)
statemap
[dirp
->d_ino
] = DIRCT
? DSTATE
: FSTATE
;
descend(idesc
, dirp
->d_ino
);
if (statemap
[dirp
->d_ino
] != CLEAR
) {
return (ret
|KEEPON
|ALTERED
);