symbolic links take on user ownership of their containing directory
[unix-history] / usr / src / sbin / ncheck / ncheck.c
index 4cdd652..32cc434 100644 (file)
@@ -1,18 +1,19 @@
-/*
- * Copyright (c) 1980 Regents of the University of California.
- * All rights reserved.  The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
+/*-
+ * Copyright (c) 1988, 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * %sccs.include.proprietary.c%
  */
 
 #ifndef lint
 char copyright[] =
  */
 
 #ifndef lint
 char copyright[] =
-"@(#) Copyright (c) 1980 Regents of the University of California.\n\
+"@(#) Copyright (c) 1988, 1990 The Regents of the University of California.\n\
  All rights reserved.\n";
  All rights reserved.\n";
-#endif not lint
+#endif /* not lint */
 
 #ifndef lint
 
 #ifndef lint
-static char sccsid[] = "@(#)ncheck.c   5.6 (Berkeley) %G%";
-#endif not lint
+static char sccsid[] = "@(#)ncheck.c   5.18 (Berkeley) %G%";
+#endif /* not lint */
 
 /*
  * ncheck -- obtain file names from reading filesystem
 
 /*
  * ncheck -- obtain file names from reading filesystem
@@ -21,15 +22,17 @@ static char sccsid[] = "@(#)ncheck.c        5.6 (Berkeley) %G%";
 #define        NB              500
 #define        MAXNINDIR       (MAXBSIZE / sizeof (daddr_t))
 
 #define        NB              500
 #define        MAXNINDIR       (MAXBSIZE / sizeof (daddr_t))
 
+#include <unistd.h>
 #include <sys/param.h>
 #include <sys/param.h>
-#include <sys/inode.h>
-#include <sys/fs.h>
 #include <sys/dir.h>
 #include <sys/dir.h>
+#include <sys/time.h>
+#include <ufs/ufs/dinode.h>
+#include <ufs/ffs/fs.h>
 #include <stdio.h>
 
 #include <stdio.h>
 
-struct fs      sblock;
-struct dinode  itab[MAXIPG];
-struct         dinode  *gip;
+struct fs      *sblockp;
+struct dinode  itab[MAXBSIZE/sizeof(struct dinode)];
+struct dinode  *gip;
 struct ilist {
        ino_t   ino;
        u_short mode;
 struct ilist {
        ino_t   ino;
        u_short mode;
@@ -60,18 +63,19 @@ int fi;
 ino_t  ino;
 int    nhent;
 int    nxfile;
 ino_t  ino;
 int    nhent;
 int    nxfile;
-long   dev_bsize = 1;
+int    dev_bsize = 1;
 
 int    nerror;
 daddr_t        bmap();
 long   atol();
 
 int    nerror;
 daddr_t        bmap();
 long   atol();
+char   *malloc(), *strcpy();
 struct htab *lookup();
 struct htab *lookup();
+struct direct *nreaddir();
 
 main(argc, argv)
        int argc;
        char *argv[];
 {
 
 main(argc, argv)
        int argc;
        char *argv[];
 {
-       register i;
        long n;
 
        while (--argc) {
        long n;
 
        while (--argc) {
@@ -84,7 +88,7 @@ main(argc, argv)
                        continue;
 
                case 'i':
                        continue;
 
                case 'i':
-                       for(iflg=0; iflg<NB; iflg++) {
+                       for(iflg=0; iflg<NB && argc >= 2; iflg++) {
                                n = atol(argv[1]);
                                if(n == 0)
                                        break;
                                n = atol(argv[1]);
                                if(n == 0)
                                        break;
@@ -104,7 +108,8 @@ main(argc, argv)
                        continue;
 
                default:
                        continue;
 
                default:
-                       fprintf(stderr, "ncheck: bad flag %c\n", (*argv)[1]);
+                       (void) fprintf(stderr, "ncheck: bad flag %c\n",
+                           (*argv)[1]);
                        nerror++;
                }
                check(*argv);
                        nerror++;
                }
                check(*argv);
@@ -116,64 +121,83 @@ check(file)
        char *file;
 {
        register int i, j, c;
        char *file;
 {
        register int i, j, c;
-       int nfiles;
 
        fi = open(file, 0);
        if(fi < 0) {
 
        fi = open(file, 0);
        if(fi < 0) {
-               fprintf(stderr, "ncheck: cannot open %s\n", file);
+               (void) fprintf(stderr, "ncheck: cannot open %s\n", file);
                nerror++;
                return;
        }
        nhent = 0;
                nerror++;
                return;
        }
        nhent = 0;
-       printf("%s:\n", file);
+       (void) printf("%s:\n", file);
        sync();
        sync();
-       bread(SBOFF, (char *)&sblock, SBSIZE);
-       if (sblock.fs_magic != FS_MAGIC) {
-               printf("%s: not a file system\n", file);
+       dev_bsize = 1;
+       sblockp = (struct fs *)malloc((unsigned)SBSIZE);
+       if (sblockp == 0) {
+               (void) printf("icheck: couldn't malloc superblock memory\n");
+               nerror++;
+               return;
+       }
+       bread((daddr_t)SBOFF, (char *)sblockp, (long)SBSIZE);
+       if (sblockp->fs_magic != FS_MAGIC) {
+               (void) printf("%s: not a file system\n", file);
                nerror++;
                return;
        }
                nerror++;
                return;
        }
-       dev_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1);
-       hsize = sblock.fs_ipg * sblock.fs_ncg - sblock.fs_cstotal.cs_nifree + 1;
-       htab = (struct htab *)malloc(hsize * sizeof(struct htab));
-       strngtab = (char *)malloc(30 * hsize);
+       dev_bsize = sblockp->fs_fsize / fsbtodb(sblockp, 1);
+       hsize = sblockp->fs_ipg * sblockp->fs_ncg -
+           sblockp->fs_cstotal.cs_nifree + 1;
+       htab = (struct htab *)malloc((unsigned)hsize * sizeof(struct htab));
+       strngtab = malloc((unsigned)(30 * hsize));
        if (htab == 0 || strngtab == 0) {
        if (htab == 0 || strngtab == 0) {
-               printf("not enough memory to allocate tables\n");
+               (void) printf("not enough memory to allocate tables\n");
                nerror++;
                return;
        }
        ino = 0;
                nerror++;
                return;
        }
        ino = 0;
-       for (c = 0; c < sblock.fs_ncg; c++) {
-               bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
-                   sblock.fs_ipg * sizeof (struct dinode));
-               for(j = 0; j < sblock.fs_ipg; j++) {
-                       if (itab[j].di_mode != 0)
-                               pass1(&itab[j]);
-                       ino++;
+       for (c = 0; c < sblockp->fs_ncg; c++) {
+               for (i = 0;
+                    i < sblockp->fs_ipg / INOPF(sblockp);
+                    i += sblockp->fs_frag) {
+                       bread(fsbtodb(sblockp, cgimin(sblockp, c) + i),
+                           (char *)itab, sblockp->fs_bsize);
+                       for (j = 0; j < INOPB(sblockp); j++) {
+                               if (itab[j].di_mode != 0)
+                                       pass1(&itab[j]);
+                               ino++;
+                       }
                }
        }
        ilist[nxfile+1].ino = 0;
        ino = 0;
                }
        }
        ilist[nxfile+1].ino = 0;
        ino = 0;
-       for (c = 0; c < sblock.fs_ncg; c++) {
-               bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
-                   sblock.fs_ipg * sizeof (struct dinode));
-               for(j = 0; j < sblock.fs_ipg; j++) {
-                       if (itab[j].di_mode != 0)
-                               pass2(&itab[j]);
-                       ino++;
+       for (c = 0; c < sblockp->fs_ncg; c++) {
+               for (i = 0;
+                    i < sblockp->fs_ipg / INOPF(sblockp);
+                    i += sblockp->fs_frag) {
+                       bread(fsbtodb(sblockp, cgimin(sblockp, c) + i),
+                           (char *)itab, sblockp->fs_bsize);
+                       for (j = 0; j < INOPB(sblockp); j++) {
+                               if (itab[j].di_mode != 0)
+                                       pass2(&itab[j]);
+                               ino++;
+                       }
                }
        }
        ino = 0;
                }
        }
        ino = 0;
-       for (c = 0; c < sblock.fs_ncg; c++) {
-               bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
-                   sblock.fs_ipg * sizeof (struct dinode));
-               for(j = 0; j < sblock.fs_ipg; j++) {
-                       if (itab[j].di_mode != 0)
-                               pass3(&itab[j]);
-                       ino++;
+       for (c = 0; c < sblockp->fs_ncg; c++) {
+               for (i = 0;
+                    i < sblockp->fs_ipg / INOPF(sblockp);
+                    i += sblockp->fs_frag) {
+                       bread(fsbtodb(sblockp, cgimin(sblockp, c) + i),
+                           (char *)itab, sblockp->fs_bsize);
+                       for (j = 0; j < INOPB(sblockp); j++) {
+                               if (itab[j].di_mode != 0)
+                                       pass3(&itab[j]);
+                               ino++;
+                       }
                }
        }
                }
        }
-       close(fi);
+       (void) close(fi);
        for (i = 0; i < hsize; i++)
                htab[i].h_ino = 0;
        for (i = iflg; i < NB; i++)
        for (i = 0; i < hsize; i++)
                htab[i].h_ino = 0;
        for (i = iflg; i < NB; i++)
@@ -205,7 +229,7 @@ pass1(ip)
                        return;
                }
        }
                        return;
                }
        }
-       lookup(ino, 1);
+       (void) lookup(ino, 1);
 }
 
 pass2(ip)
 }
 
 pass2(ip)
@@ -220,7 +244,7 @@ pass2(ip)
        dirp.loc = 0;
        dirp.ip = ip;
        gip = ip;
        dirp.loc = 0;
        dirp.ip = ip;
        gip = ip;
-       for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
+       for (dp = nreaddir(&dirp); dp != NULL; dp = nreaddir(&dirp)) {
                if(dp->d_ino == 0)
                        continue;
                hp = lookup(dp->d_ino, 0);
                if(dp->d_ino == 0)
                        continue;
                hp = lookup(dp->d_ino, 0);
@@ -231,7 +255,7 @@ pass2(ip)
                hp->h_pino = ino;
                hp->h_name = &strngtab[strngloc];
                strngloc += strlen(dp->d_name) + 1;
                hp->h_pino = ino;
                hp->h_name = &strngtab[strngloc];
                strngloc += strlen(dp->d_name) + 1;
-               strcpy(hp->h_name, dp->d_name);
+               (void) strcpy(hp->h_name, dp->d_name);
        }
 }
 
        }
 }
 
@@ -247,7 +271,7 @@ pass3(ip)
        dirp.loc = 0;
        dirp.ip = ip;
        gip = ip;
        dirp.loc = 0;
        dirp.ip = ip;
        gip = ip;
-       for(dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
+       for(dp = nreaddir(&dirp); dp != NULL; dp = nreaddir(&dirp)) {
                if(aflg==0 && dotname(dp))
                        continue;
                if(sflg == 0 && iflg == 0)
                if(aflg==0 && dotname(dp))
                        continue;
                if(sflg == 0 && iflg == 0)
@@ -258,15 +282,15 @@ pass3(ip)
                if (ilist[k].ino == 0)
                        continue;
                if (mflg)
                if (ilist[k].ino == 0)
                        continue;
                if (mflg)
-                       printf("mode %-6o uid %-5d gid %-5d ino ",
+                       (void) printf("mode %-6o uid %-5d gid %-5d ino ",
                            ilist[k].mode, ilist[k].uid, ilist[k].gid);
        pr:
                            ilist[k].mode, ilist[k].uid, ilist[k].gid);
        pr:
-               printf("%-5u\t", dp->d_ino);
+               (void) printf("%-5lu\t", dp->d_ino);
                pname(ino, 0);
                pname(ino, 0);
-               printf("/%s", dp->d_name);
+               (void) printf("/%s", dp->d_name);
                if (lookup(dp->d_ino, 0))
                if (lookup(dp->d_ino, 0))
-                       printf("/.");
-               printf("\n");
+                       (void) printf("/.");
+               (void) printf("\n");
        }
 }
 
        }
 }
 
@@ -274,7 +298,7 @@ pass3(ip)
  * get next entry in a directory.
  */
 struct direct *
  * get next entry in a directory.
  */
 struct direct *
-readdir(dirp)
+nreaddir(dirp)
        register struct dirstuff *dirp;
 {
        register struct direct *dp;
        register struct dirstuff *dirp;
 {
        register struct direct *dp;
@@ -283,16 +307,16 @@ readdir(dirp)
        for(;;) {
                if (dirp->loc >= dirp->ip->di_size)
                        return NULL;
        for(;;) {
                if (dirp->loc >= dirp->ip->di_size)
                        return NULL;
-               if (blkoff(&sblock, dirp->loc) == 0) {
-                       lbn = lblkno(&sblock, dirp->loc);
+               if (blkoff(sblockp, dirp->loc) == 0) {
+                       lbn = lblkno(sblockp, dirp->loc);
                        d = bmap(lbn);
                        if(d == 0)
                                return NULL;
                        d = bmap(lbn);
                        if(d == 0)
                                return NULL;
-                       bread(fsbtodb(&sblock, d), dirp->dbuf,
-                           dblksize(&sblock, dirp->ip, lbn));
+                       bread(fsbtodb(sblockp, d), dirp->dbuf,
+                             (long)dblksize(sblockp, dirp->ip, lbn));
                }
                dp = (struct direct *)
                }
                dp = (struct direct *)
-                   (dirp->dbuf + blkoff(&sblock, dirp->loc));
+                   (dirp->dbuf + blkoff(sblockp, dirp->loc));
                dirp->loc += dp->d_reclen;
                if (dp->d_ino == 0)
                        continue;
                dirp->loc += dp->d_reclen;
                if (dp->d_ino == 0)
                        continue;
@@ -320,15 +344,15 @@ pname(i, lev)
        if (i==ROOTINO)
                return;
        if ((hp = lookup(i, 0)) == 0) {
        if (i==ROOTINO)
                return;
        if ((hp = lookup(i, 0)) == 0) {
-               printf("???");
+               (void) printf("???");
                return;
        }
        if (lev > 10) {
                return;
        }
        if (lev > 10) {
-               printf("...");
+               (void) printf("...");
                return;
        }
        pname(hp->h_pino, ++lev);
                return;
        }
        pname(hp->h_pino, ++lev);
-       printf("/%s", hp->h_name);
+       (void) printf("/%s", hp->h_name);
 }
 
 struct htab *
 }
 
 struct htab *
@@ -347,25 +371,45 @@ lookup(i, ef)
        if (ef==0)
                return(0);
        if (++nhent >= hsize) {
        if (ef==0)
                return(0);
        if (++nhent >= hsize) {
-               fprintf(stderr, "ncheck: hsize of %d is too small\n", hsize);
+               (void) fprintf(stderr, "ncheck: hsize of %ld is too small\n",
+                   hsize);
                exit(1);
        }
        hp->h_ino = i;
        return(hp);
 }
 
                exit(1);
        }
        hp->h_ino = i;
        return(hp);
 }
 
-bread(bno, buf, cnt)
+bread(bno, buf, lcount)
        daddr_t bno;
        daddr_t bno;
-       char *buf;
-       int cnt;
+       register char *buf;
+       long lcount;
 {
 {
-       register i;
+       register int i, cnt = lcount;
+       register off_t off = bno * dev_bsize;
 
 
-       lseek(fi, bno * dev_bsize, 0);
+       (void) lseek(fi, off, SEEK_SET);
        if (read(fi, buf, cnt) != cnt) {
        if (read(fi, buf, cnt) != cnt) {
-               fprintf(stderr, "ncheck: read error %d\n", bno);
-               for(i=0; i < cnt; i++)
-                       buf[i] = 0;
+               (void) fprintf(stderr, "ncheck: read error %ld\n", bno);
+               if (cnt % dev_bsize) {
+                       /* THIS INDICATES A SERIOUS BUG */
+                       /* bzero is probably not correct, but will do */
+                       (void) fprintf(stderr,
+                           "ncheck: bread: cnt %d not multiple of %d\n",
+                           cnt, dev_bsize);
+                       bzero(buf, cnt);
+                       return;
+               }
+               for (i = 0; i < cnt; i += dev_bsize) {
+                       (void) lseek(fi, off, SEEK_SET);
+                       if (read(fi, buf, dev_bsize) != dev_bsize) {
+                               (void) fprintf(stderr,
+                                   "ncheck: re-read error %ld\n", bno);
+                               bzero(buf, dev_bsize);
+                       }
+                       off += dev_bsize;
+                       buf += dev_bsize;
+                       bno++;
+               }
        }
 }
 
        }
 }
 
@@ -385,7 +429,7 @@ bmap(bn)
        daddr_t nb, *bap;
 
        if (bn < 0) {
        daddr_t nb, *bap;
 
        if (bn < 0) {
-               fprintf(stderr, "ncheck: bn %d negative\n", bn);
+               (void) fprintf(stderr, "ncheck: bn %ld negative\n", bn);
                return ((daddr_t)0);
        }
 
                return ((daddr_t)0);
        }
 
@@ -402,13 +446,13 @@ bmap(bn)
        sh = 1;
        bn -= NDADDR;
        for (j = NIADDR; j > 0; j--) {
        sh = 1;
        bn -= NDADDR;
        for (j = NIADDR; j > 0; j--) {
-               sh *= NINDIR(&sblock);
+               sh *= NINDIR(sblockp);
                if (bn < sh)
                        break;
                bn -= sh;
        }
        if (j == 0) {
                if (bn < sh)
                        break;
                bn -= sh;
        }
        if (j == 0) {
-               printf("ncheck: bn %ld ovf, ino %u\n", bn, ino);
+               (void) printf("ncheck: bn %ld ovf, ino %lu\n", bn, ino);
                return ((daddr_t)0);
        }
 
                return ((daddr_t)0);
        }
 
@@ -417,7 +461,7 @@ bmap(bn)
         */
        nb = gip->di_ib[NIADDR - j];
        if (nb == 0) {
         */
        nb = gip->di_ib[NIADDR - j];
        if (nb == 0) {
-               printf("ncheck: bn %ld void1, ino %u\n", bn, ino);
+               (void) printf("ncheck: bn %ld void1, ino %lu\n", bn, ino);
                return ((daddr_t)0);
        }
 
                return ((daddr_t)0);
        }
 
@@ -426,15 +470,16 @@ bmap(bn)
         */
        for (; j <= NIADDR; j++) {
                if (blknos[j] != nb) {
         */
        for (; j <= NIADDR; j++) {
                if (blknos[j] != nb) {
-                       bread(fsbtodb(&sblock, nb), b[j], sblock.fs_bsize);
+                       bread(fsbtodb(sblockp, nb), b[j], sblockp->fs_bsize);
                        blknos[j] = nb;
                }
                bap = (daddr_t *)b[j];
                        blknos[j] = nb;
                }
                bap = (daddr_t *)b[j];
-               sh /= NINDIR(&sblock);
-               i = (bn / sh) % NINDIR(&sblock);
+               sh /= NINDIR(sblockp);
+               i = (bn / sh) % NINDIR(sblockp);
                nb = bap[i];
                if(nb == 0) {
                nb = bap[i];
                if(nb == 0) {
-                       printf("ncheck: bn %ld void2, ino %u\n", bn, ino);
+                       (void) printf("ncheck: bn %ld void2, ino %lu\n", bn,
+                           ino);
                        return ((daddr_t)0);
                }
        }
                        return ((daddr_t)0);
                }
        }