make readdir more robust; allow printing of dir entries not on tape
[unix-history] / usr / src / sbin / fsck / main.c
index 6736883..5aec981 100644 (file)
@@ -1,4 +1,4 @@
-char version[] = "@(#)main.c   2.17    (Berkeley)      %G%";
+char version[] = "@(#)main.c   2.22    (Berkeley)      %G%";
 
 #include <stdio.h>
 #include <ctype.h>
 
 #include <stdio.h>
 #include <ctype.h>
@@ -34,6 +34,8 @@ typedef struct direct DIRECT;
 #define        BLK     ((dp->di_mode & IFMT) == IFBLK)
 #define        CHR     ((dp->di_mode & IFMT) == IFCHR)
 #define        LNK     ((dp->di_mode & IFMT) == IFLNK)
 #define        BLK     ((dp->di_mode & IFMT) == IFBLK)
 #define        CHR     ((dp->di_mode & IFMT) == IFCHR)
 #define        LNK     ((dp->di_mode & IFMT) == IFLNK)
+#define        SOCK    ((dp->di_mode & IFMT) == IFSOCK)
+#define        BADBLK  ((dp->di_mode & IFMT) == IFMT)
 #define        SPECIAL (BLK || CHR)
 
 ino_t  startinum;              /* blk num of first in raw area */
 #define        SPECIAL (BLK || CHR)
 
 ino_t  startinum;              /* blk num of first in raw area */
@@ -81,7 +83,7 @@ daddr_t       duplist[DUPTBLSIZE];    /* dup block table */
 daddr_t        *enddup;                /* next entry in dup table */
 daddr_t        *muldup;                /* multiple dups part of table */
 
 daddr_t        *enddup;                /* next entry in dup table */
 daddr_t        *muldup;                /* multiple dups part of table */
 
-#define        MAXLNCNT        50      /* num zero link cnts to remember */
+#define        MAXLNCNT        500     /* num zero link cnts to remember */
 ino_t  badlncnt[MAXLNCNT];     /* table of inos with zero link cnts */
 ino_t  *badlnp;                /* next entry in table */
 
 ino_t  badlncnt[MAXLNCNT];     /* table of inos with zero link cnts */
 ino_t  *badlnp;                /* next entry in table */
 
@@ -104,6 +106,7 @@ char        *pathp;                 /* pointer to pathname position */
 char   *thisname;              /* ptr to current pathname component */
 char   *srchname;              /* name being searched for in dir */
 char   pathname[BUFSIZ];
 char   *thisname;              /* ptr to current pathname component */
 char   *srchname;              /* name being searched for in dir */
 char   pathname[BUFSIZ];
+char   *endpathname = &pathname[BUFSIZ - 2];
 
 char   *lfname = "lost+found";
 
 
 char   *lfname = "lost+found";
 
@@ -289,7 +292,7 @@ retry:
                if (stchar.st_mode & S_IFCHR) {
                        if (stslash.st_dev == stblock.st_rdev) {
                                hotroot++;
                if (stchar.st_mode & S_IFCHR) {
                        if (stslash.st_dev == stblock.st_rdev) {
                                hotroot++;
-                               raw = unrawname(name);
+                               raw = rawname(name);
                        }
                        checkfilesys(raw);
                        return (1);
                        }
                        checkfilesys(raw);
                        return (1);
@@ -583,7 +586,12 @@ pass1()
                                }
                                n--;
                                lastino = inum;
                                }
                                n--;
                                lastino = inum;
-                               if (ftypeok(dp) == 0)
+                               if (!preen && BADBLK &&
+                                   reply("HOLD BAD BLOCK") == 1) {
+                                       dp->di_size = sblock.fs_fsize;
+                                       dp->di_mode = IFREG|0600;
+                                       inodirty();
+                               } else if (ftypeok(dp) == 0)
                                        goto unknown;
                                if (dp->di_size < 0) {
                                        if (debug)
                                        goto unknown;
                                if (dp->di_size < 0) {
                                        if (debug)
@@ -597,7 +605,8 @@ pass1()
                                for (j = ndb; j < NDADDR; j++)
                                        if (dp->di_db[j] != 0) {
                                                if (debug)
                                for (j = ndb; j < NDADDR; j++)
                                        if (dp->di_db[j] != 0) {
                                                if (debug)
-                                                       printf("bad direct addr:");
+                                                       printf("bad direct addr: %d\n",
+                                                               dp->di_db[j]);
                                                goto unknown;
                                        }
                                for (j = 0, ndb -= NDADDR; ndb > 0; j++)
                                                goto unknown;
                                        }
                                for (j = 0, ndb -= NDADDR; ndb > 0; j++)
@@ -605,7 +614,8 @@ pass1()
                                for (; j < NIADDR; j++)
                                        if (dp->di_ib[j] != 0) {
                                                if (debug)
                                for (; j < NIADDR; j++)
                                        if (dp->di_ib[j] != 0) {
                                                if (debug)
-                                                       printf("bad indirect addr:");
+                                                       printf("bad indirect addr: %d\n",
+                                                               dp->di_ib[j]);
                                                goto unknown;
                                        }
                                n_files++;
                                                goto unknown;
                                        }
                                n_files++;
@@ -624,8 +634,9 @@ pass1()
                                ckinode(dp, ADDR);
                                continue;
                unknown:
                                ckinode(dp, ADDR);
                                continue;
                unknown:
-                               pfatal("UNKNOWN FILE TYPE I=%u", inum);
-                               if (reply("CLEAR") == 1) {
+                               if (!SOCK)
+                                       pfatal("UNKNOWN FILE TYPE I=%u", inum);
+                               if ((preen && SOCK) || reply("CLEAR") == 1) {
                                        zapino(dp);
                                        inodirty();
                                        inosumbad++;
                                        zapino(dp);
                                        inodirty();
                                        inosumbad++;
@@ -815,6 +826,10 @@ pass2check(dirp)
        if ((inum = dirp->d_ino) == 0)
                return (KEEPON);
        thisname = pathp;
        if ((inum = dirp->d_ino) == 0)
                return (KEEPON);
        thisname = pathp;
+       if (pathp + dirp->d_namlen >= endpathname) {
+               *pathp = '\0';
+               errexit("NAME TOO LONG %s%s\n", pathname, dirp->d_name);
+       }
        for (p = dirp->d_name; p < &dirp->d_name[MAXNAMLEN]; )
                if ((*pathp++ = *p++) == 0) {
                        --pathp;
        for (p = dirp->d_name; p < &dirp->d_name[MAXNAMLEN]; )
                if ((*pathp++ = *p++) == 0) {
                        --pathp;
@@ -963,7 +978,7 @@ pass5()
        daddr_t cbase;
        int blockbits = (1<<sblock.fs_frag)-1;
 
        daddr_t cbase;
        int blockbits = (1<<sblock.fs_frag)-1;
 
-       blkcpy((unsigned)bmapsz, blockmap, freemap);
+       bcopy(blockmap, freemap, (unsigned)bmapsz);
        dupblk = 0;
        n_index = sblock.fs_ncg * (cgdmin(&sblock, 0) - cgtod(&sblock, 0));
        for (c = 0; c < sblock.fs_ncg; c++) {
        dupblk = 0;
        n_index = sblock.fs_ncg * (cgdmin(&sblock, 0) - cgtod(&sblock, 0));
        for (c = 0; c < sblock.fs_ncg; c++) {
@@ -1302,12 +1317,9 @@ readdir(dirp)
                dirp->loc += DIRBLKSIZ;
                filsize -= DIRBLKSIZ;
                if (dirp->fix == DONTKNOW) {
                dirp->loc += DIRBLKSIZ;
                filsize -= DIRBLKSIZ;
                if (dirp->fix == DONTKNOW) {
-                       pwarn("DIRECTORY %D CORRUPTED", dirp->number);
+                       pfatal("DIRECTORY %D CORRUPTED", dirp->number);
                        dirp->fix = NOFIX;
                        dirp->fix = NOFIX;
-                       if (preen) {
-                               printf(" (SALVAGED)\n");
-                               dirp->fix = FIX;
-                       } else if (reply("SALVAGE") != 0)
+                       if (reply("SALVAGE") != 0)
                                dirp->fix = FIX;
                }
                if (dirp->fix != FIX)
                                dirp->fix = FIX;
                }
                if (dirp->fix != FIX)
@@ -1333,12 +1345,9 @@ readdir(dirp)
                dirp->loc += size;
                filsize -= size;
                if (dirp->fix == DONTKNOW) {
                dirp->loc += size;
                filsize -= size;
                if (dirp->fix == DONTKNOW) {
-                       pwarn("DIRECTORY %D CORRUPTED", dirp->number);
+                       pfatal("DIRECTORY %D CORRUPTED", dirp->number);
                        dirp->fix = NOFIX;
                        dirp->fix = NOFIX;
-                       if (preen) {
-                               printf(" (SALVAGED)\n");
-                               dirp->fix = FIX;
-                       } else if (reply("SALVAGE") != 0)
+                       if (reply("SALVAGE") != 0)
                                dirp->fix = FIX;
                }
                if (dirp->fix == FIX) {
                                dirp->fix = FIX;
                }
                if (dirp->fix == FIX) {
@@ -1962,7 +1971,7 @@ errexit(s1, s2, s3, s4)
 
 /*
  * An inconsistency occured which shouldn't during normal operations.
 
 /*
  * An inconsistency occured which shouldn't during normal operations.
- * Die if preening, otw just printf.
+ * Die if preening, otherwise just printf.
  */
 /* VARARGS1 */
 pfatal(s, a1, a2, a3)
  */
 /* VARARGS1 */
 pfatal(s, a1, a2, a3)