1: /*
   2:  * Copyright (c) 1980 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  */
   6: 
   7: #if !defined(lint) && defined(DOSCCS)
   8: char copyright[] =
   9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
  10:  All rights reserved.\n";
  11: static char sccsid[] = "@(#)dcheck.c	5.1 (Berkeley) 6/6/85";
  12: #endif
  13: 
  14: /*
  15:  * dcheck - check directory consistency
  16:  */
  17: #define NI  8
  18: #define NF  2048
  19: #define NB  10
  20: #define MAXNINDIR   (MAXBSIZE / sizeof (daddr_t))
  21: 
  22: #include <sys/param.h>
  23: #include <sys/inode.h>
  24: #include <sys/fs.h>
  25: #include <sys/dir.h>
  26: #include <sys/file.h>
  27: #include <stdio.h>
  28: 
  29: union {
  30:     struct  fs fs;
  31:     char pad[MAXBSIZE];
  32: } fsun;
  33: #define sblock  fsun.fs
  34: 
  35: struct dirstuff {
  36:     off_t loc;
  37:     struct dinode *ip;
  38:     char dbuf[MAXBSIZE];
  39: };
  40: 
  41: struct  dinode  itab[NI * INOPB];
  42: struct  dinode  *gip;
  43: ino_t   ilist[NB];
  44: 
  45: int fi;
  46: int fo;
  47: ino_t   ino;
  48: ino_t   ecount[NF];
  49: ino_t   starti, endi;
  50: int edirty;
  51: char    *tfn = "/tmp/dchkXXXXXX";
  52: int headpr;
  53: ino_t   nfiles;
  54: 
  55: int nerror;
  56: daddr_t bmap();
  57: extern long atol(), lseek();
  58: extern char *malloc();
  59: extern  int errno;
  60: 
  61: main(argc, argv)
  62: char *argv[];
  63: {
  64:     register i;
  65:     long n;
  66: 
  67:     mktemp(tfn);
  68:     fo = open(tfn, O_CREAT|O_RDWR, 0600);
  69:     if (fo < 0) {
  70:         fprintf(stderr, "Can't create tmp file: %s\n", tfn);
  71:         exit(4);
  72:     }
  73:     unlink(tfn);
  74: 
  75:     while (--argc) {
  76:         argv++;
  77:         if (**argv=='-')
  78:         switch ((*argv)[1]) {
  79: 
  80:         case 'i':
  81:             for(i=0; i<NB; i++) {
  82:                 n = atol(argv[1]);
  83:                 if(n == 0)
  84:                     break;
  85:                 ilist[i] = (ino_t)n;
  86:                 argv++;
  87:                 argc--;
  88:             }
  89:             ilist[i] = 0;
  90:             continue;
  91: 
  92:         default:
  93:             printf("Bad flag %c\n", (*argv)[1]);
  94:             nerror++;
  95:         }
  96:         check(*argv);
  97:     }
  98:     return(nerror);
  99: }
 100: 
 101: check(file)
 102: char *file;
 103: {
 104:     register i, j;
 105: 
 106:     fi = open(file, 0);
 107:     if(fi < 0) {
 108:         printf("cannot open %s\n", file);
 109:         nerror++;
 110:         return;
 111:     }
 112: 
 113:     bread(SBLOCK, (char *)&sblock, SBSIZE);
 114:     nfiles = (sblock.fs_isize - 2) * INOPB;
 115:     bzero(ecount, sizeof (ecount));
 116: 
 117:     lseek(fo, 0L, 0);
 118:     ftruncate(fo, 0L);
 119:     lseek(fo, (off_t)nfiles * sizeof (u_short), 0);
 120:     write(fo, ecount, sizeof (ecount));
 121: 
 122:     headpr = 0;
 123:     printf("%s:\n", file);
 124:     sync();
 125:     ino = 0;
 126:     for (i = 2; ; i += NI) {
 127:         if (ino >= nfiles)
 128:             break;
 129:         bread((daddr_t)i, (char *)itab, sizeof (itab));
 130:         for (j = 0; j < INOPB * NI; j++) {
 131:             if (ino >= nfiles)
 132:                 break;
 133:             ino++;
 134:             pass1(&itab[j]);
 135:         }
 136:     }
 137:     ino = 0;
 138:     for (i = 2; ; i += NI) {
 139:         if (ino >= nfiles)
 140:             break;
 141:         bread((daddr_t)i, (char *)itab, sizeof (itab));
 142:         for (j = 0; j < INOPB * NI; j++) {
 143:             if (ino >= nfiles)
 144:                 break;
 145:             ino++;
 146:             pass1(&itab[j]);
 147:         }
 148:     }
 149: }
 150: 
 151: pass1(ip)
 152:     register struct dinode *ip;
 153: {
 154:     register struct direct *dp;
 155:     struct dirstuff dirp;
 156:     register int k;
 157: 
 158:     if((ip->di_mode&IFMT) != IFDIR)
 159:         return;
 160:     dirp.loc = 0;
 161:     dirp.ip = ip;
 162:     gip = ip;
 163:     for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
 164:         if(dp->d_ino == 0)
 165:             continue;
 166:         if(dp->d_ino > nfiles || dp->d_ino < ROOTINO) {
 167:             printf("%u bad; %u/%s\n",
 168:                 dp->d_ino, ino, dp->d_name);
 169:             nerror++;
 170:             continue;
 171:         }
 172:         for (k = 0; ilist[k] != 0; k++)
 173:             if (ilist[k] == dp->d_ino) {
 174:                 printf("%u arg; %u/%s\n",
 175:                      dp->d_ino, ino, dp->d_name);
 176:                 nerror++;
 177:             }
 178:         dolncnt((ino_t)dp->d_ino, 1);
 179:     }
 180: }
 181: 
 182: pass2(ip)
 183: register struct dinode *ip;
 184: {
 185:     register ino_t i;
 186:     register u_short cnt;
 187: 
 188:     i = ino;
 189:     cnt = dolncnt(i, 0);
 190:     if ((ip->di_mode&IFMT)==0 && cnt==0)
 191:         return;
 192:     if (ip->di_nlink==cnt && ip->di_nlink!=0)
 193:         return;
 194:     if (headpr==0) {
 195:         printf("     entries  link cnt\n");
 196:         headpr++;
 197:     }
 198:     printf("%u\t%d\t%d\n", ino, cnt, ip->di_nlink);
 199: }
 200: 
 201: /*
 202:  * get next entry in a directory.
 203:  */
 204: struct direct *
 205: readdir(dirp)
 206:     register struct dirstuff *dirp;
 207: {
 208:     register struct direct *dp;
 209:     daddr_t lbn, d;
 210: 
 211:     for(;;) {
 212:         if (dirp->loc >= dirp->ip->di_size)
 213:             return NULL;
 214:         if ((lbn = lblkno(dirp->loc)) == 0) {
 215:             d = bmap(lbn);
 216:             if(d == 0)
 217:                 return NULL;
 218:             bread(d, dirp->dbuf, DEV_BSIZE);
 219:         }
 220:         dp = (struct direct *)(dirp->dbuf + blkoff(dirp->loc));
 221:         dirp->loc += dp->d_reclen;
 222:         if (dp->d_ino == 0)
 223:             continue;
 224:         return (dp);
 225:     }
 226: }
 227: 
 228: bread(bno, buf, cnt)
 229: daddr_t bno;
 230: char *buf;
 231: {
 232: 
 233:     lseek(fi, bno * DEV_BSIZE, 0);
 234:     if (read(fi, buf, cnt) != cnt) {
 235:         printf("read error %ld\n", bno);
 236:         bzero(buf, cnt);
 237:     }
 238: }
 239: 
 240: daddr_t
 241: bmap(i)
 242:     daddr_t i;
 243: {
 244:     daddr_t ibuf[MAXNINDIR];
 245: 
 246:     if(i < NDADDR)
 247:         return(gip->di_addr[i]);
 248:     i -= NDADDR;
 249:     if(i > NINDIR) {
 250:         printf("%u - huge directory\n", ino);
 251:         return((daddr_t)0);
 252:     }
 253:     bread(gip->di_addr[NDADDR], (char *)ibuf, sizeof(ibuf));
 254:     return(ibuf[i]);
 255: }
 256: 
 257: u_short
 258: dolncnt(i, cnt)
 259:     register ino_t i;
 260:     register u_short cnt;
 261: {
 262: again:
 263:     if (i >= starti && i <= endi) {
 264:         if (cnt)
 265:             edirty = 1;
 266:         ecount[i - starti] += cnt;
 267:         return(ecount[i - starti]);
 268:     }
 269:     fill(i);
 270:     goto again;
 271: }
 272: 
 273: flush()
 274: {
 275: 
 276:     if (edirty) {
 277:         edirty = 0;
 278:         if (lseek(fo, (off_t)(starti / NF) * sizeof (ecount), 0) < 0) {
 279:             fprintf(stderr, "lseek error %d in tmp file\n", errno);
 280:             return;
 281:         }
 282:         if (write(fo, ecount, sizeof (ecount)) != sizeof (ecount)) {
 283:             fprintf(stderr, "write error %d in tmp file\n", errno);
 284:             return;
 285:         }
 286:     }
 287: }
 288: 
 289: fill(i)
 290: register ino_t i;
 291: {
 292:     flush();
 293:     starti = (i / NF) * NF;
 294:     endi = starti + NF - 1;
 295:     if (lseek(fo, (off_t)(starti/NF) * sizeof (ecount), 0) < 0) {
 296:         fprintf(stderr, "lseek error %d in tmp file\n", errno);
 297:         return;
 298:     }
 299:     if (read(fo, ecount, sizeof (ecount)) != sizeof (ecount)) {
 300:         fprintf(stderr, "read error %d in tmp file\n", errno);
 301:         return;
 302:     }
 303: }

Defined functions

bmap defined in line 240; used 2 times
bread defined in line 228; used 5 times
check defined in line 101; used 1 times
  • in line 96
dolncnt defined in line 257; used 2 times
fill defined in line 289; used 1 times
flush defined in line 273; used 1 times
main defined in line 61; never used
pass1 defined in line 151; used 2 times
pass2 defined in line 182; never used
readdir defined in line 204; used 2 times
  • in line 163(2)

Defined variables

copyright defined in line 8; never used
ecount defined in line 48; used 14 times
edirty defined in line 50; used 3 times
endi defined in line 49; used 2 times
fi defined in line 45; used 4 times
fo defined in line 46; used 10 times
gip defined in line 42; used 3 times
headpr defined in line 52; used 3 times
ilist defined in line 43; used 4 times
ino defined in line 47; used 13 times
itab defined in line 41; used 6 times
nerror defined in line 55; used 5 times
nfiles defined in line 53; used 7 times
sccsid defined in line 11; never used
starti defined in line 49; used 7 times
tfn defined in line 51; used 4 times

Defined struct's

dirstuff defined in line 35; used 4 times

Defined macros

MAXNINDIR defined in line 20; used 1 times
NB defined in line 19; used 2 times
NF defined in line 18; used 6 times
NI defined in line 17; used 5 times
sblock defined in line 33; used 2 times
Last modified: 1990-09-14
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4389
Valid CSS Valid XHTML 1.0 Strict