minor cleanups for cray
[unix-history] / usr / src / old / dcheck / dcheck.c
/*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*/
#ifndef lint
char copyright[] =
"@(#) Copyright (c) 1980 Regents of the University of California.\n\
All rights reserved.\n";
#endif not lint
#ifndef lint
static char sccsid[] = "@(#)dcheck.c 5.3 (Berkeley) %G%";
#endif not lint
/*
* dcheck - check directory consistency
*/
#define NB 10
#define MAXNINDIR (MAXBSIZE / sizeof (daddr_t))
#include <sys/param.h>
#include <sys/inode.h>
#include <sys/fs.h>
#include <sys/dir.h>
#include <stdio.h>
union {
struct fs fs;
char pad[SBSIZE];
} fsun;
#define sblock fsun.fs
struct dirstuff {
int loc;
struct dinode *ip;
char dbuf[MAXBSIZE];
};
struct dinode itab[MAXBSIZE / sizeof(struct dinode)];
struct dinode *gip;
ino_t ilist[NB];
int fi;
ino_t ino;
ino_t *ecount;
int headpr;
int nfiles;
long dev_bsize = 1;
int nerror;
daddr_t bmap();
long atol();
char *malloc();
main(argc, argv)
char *argv[];
{
register i;
long n;
while (--argc) {
argv++;
if (**argv=='-')
switch ((*argv)[1]) {
case 'i':
for(i=0; i<NB; i++) {
n = atol(argv[1]);
if(n == 0)
break;
ilist[i] = n;
argv++;
argc--;
}
ilist[i] = 0;
continue;
default:
printf("Bad flag %c\n", (*argv)[1]);
nerror++;
}
check(*argv);
}
return(nerror);
}
check(file)
char *file;
{
register i, j, c;
fi = open(file, 0);
if(fi < 0) {
printf("cannot open %s\n", file);
nerror++;
return;
}
headpr = 0;
printf("%s:\n", file);
sync();
bread(SBOFF, (char *)&sblock, SBSIZE);
if (sblock.fs_magic != FS_MAGIC) {
printf("%s: not a file system\n", file);
nerror++;
return;
}
dev_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1);
nfiles = sblock.fs_ipg * sblock.fs_ncg;
ecount = (ino_t *)malloc((nfiles+1) * sizeof (*ecount));
if (ecount == 0) {
printf("%s: not enough core for %d files\n", file, nfiles);
exit(04);
}
for (i = 0; i<=nfiles; i++)
ecount[i] = 0;
ino = 0;
for (c = 0; c < sblock.fs_ncg; c++) {
for (i = 0;
i < sblock.fs_ipg / INOPF(&sblock);
i += sblock.fs_frag) {
bread(fsbtodb(&sblock, cgimin(&sblock, c) + i),
(char *)itab, sblock.fs_bsize);
for (j = 0; j < INOPB(&sblock); j++) {
pass1(&itab[j]);
ino++;
}
}
}
ino = 0;
for (c = 0; c < sblock.fs_ncg; c++) {
for (i = 0;
i < sblock.fs_ipg / INOPF(&sblock);
i += sblock.fs_frag) {
bread(fsbtodb(&sblock, cgimin(&sblock, c) + i),
(char *)itab, sblock.fs_bsize);
for (j = 0; j < INOPB(&sblock); j++) {
pass2(&itab[j]);
ino++;
}
}
}
free(ecount);
}
pass1(ip)
register struct dinode *ip;
{
register struct direct *dp;
struct dirstuff dirp;
int k;
if((ip->di_mode&IFMT) != IFDIR)
return;
dirp.loc = 0;
dirp.ip = ip;
gip = ip;
for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
if(dp->d_ino == 0)
continue;
if(dp->d_ino > nfiles || dp->d_ino < ROOTINO) {
printf("%d bad; %d/%s\n",
dp->d_ino, ino, dp->d_name);
nerror++;
continue;
}
for (k = 0; ilist[k] != 0; k++)
if (ilist[k] == dp->d_ino) {
printf("%d arg; %d/%s\n",
dp->d_ino, ino, dp->d_name);
nerror++;
}
ecount[dp->d_ino]++;
}
}
pass2(ip)
register struct dinode *ip;
{
register i;
i = ino;
if ((ip->di_mode&IFMT)==0 && ecount[i]==0)
return;
if (ip->di_nlink==ecount[i] && ip->di_nlink!=0)
return;
if (headpr==0) {
printf(" entries link cnt\n");
headpr++;
}
printf("%u\t%d\t%d\n", ino,
ecount[i], ip->di_nlink);
}
/*
* get next entry in a directory.
*/
struct direct *
readdir(dirp)
register struct dirstuff *dirp;
{
register struct direct *dp;
daddr_t lbn, d;
for(;;) {
if (dirp->loc >= dirp->ip->di_size)
return NULL;
if ((lbn = lblkno(&sblock, dirp->loc)) == 0) {
d = bmap(lbn);
if(d == 0)
return NULL;
bread(fsbtodb(&sblock, d), dirp->dbuf,
dblksize(&sblock, dirp->ip, lbn));
}
dp = (struct direct *)
(dirp->dbuf + blkoff(&sblock, dirp->loc));
dirp->loc += dp->d_reclen;
if (dp->d_ino == 0)
continue;
return (dp);
}
}
bread(bno, buf, cnt)
daddr_t bno;
char *buf;
{
register i;
lseek(fi, bno * dev_bsize, 0);
if (read(fi, buf, cnt) != cnt) {
printf("read error %d\n", bno);
for(i=0; i < cnt; i++)
buf[i] = 0;
}
}
daddr_t
bmap(i)
{
daddr_t ibuf[MAXNINDIR];
if(i < NDADDR)
return(gip->di_db[i]);
i -= NDADDR;
if(i > NINDIR(&sblock)) {
printf("%u - huge directory\n", ino);
return((daddr_t)0);
}
bread(fsbtodb(&sblock, gip->di_ib[0]), (char *)ibuf, sizeof(ibuf));
return(ibuf[i]);
}