Ultrix-3.1/src/cmd/ncheck/ncheck.c

Compare this file to the similar file:
Show the results in this format:


/**********************************************************************
 *   Copyright (c) Digital Equipment Corporation 1984, 1985, 1986.    *
 *   All Rights Reserved. 					      *
 *   Reference "/usr/src/COPYRIGHT" for applicable restrictions.      *
 **********************************************************************/

/*
 * ncheck -- obtain file names from reading filesystem
 */

static char Sccsid[] = "@(#)ncheck.c 3.0 4/21/86";

/*
 * WARNING:
 * ncheck uses it's own internal version of printf. An
 * additional argument is used to indicate stdout or stderr.
 * It does not accept all the formats of standard printf.
 * This is done to fit the process within size limits for
 * non-separate I&D machines.
 */

/* #include <stdio.h> */
#include <sys/param.h>
#include <sys/inode.h>
#include <sys/ino.h>
#include <sys/dir.h>
#include <sys/filsys.h>
#include <sys/fblk.h>


#ifdef	UCB_NKB
#define	NI	8
#else
#define	NI	16
#endif  UCB_NKB

#define	NB	100

#ifdef	NCHECK40
#define	HSIZE	2350
#else
#define	HSIZE	2503
#endif 	NCHECK40
#define	NDIR	(BSIZE/sizeof(struct direct))

struct	filsys	sblock;
struct	dinode	itab[INOPB*NI];
daddr_t	iaddr[NADDR];
ino_t	ilist[NB];
struct	htab
{
	ino_t	h_ino;
	ino_t	h_pino;
	char	h_name[DIRSIZ];
} htab[HSIZE];

int	aflg;
int	sflg;
int	fi;
ino_t	ino;
int	nhent;
int	nxfile;

int	nerror;
daddr_t	bmap();
long	atol();
struct htab *lookup();
char tmpbuf[14];

main(argc, argv)
char *argv[];
{
	register i;
	long n;

	while (--argc) {
		argv++;
		if (**argv=='-')
		switch ((*argv)[1]) {

		case 'a':
			aflg++;
			continue;

		case 'i':
			for(i=0; i<NB; i++) {
				n = atol(argv[1]);
				if(n == 0)
					break;
				ilist[i] = n;
				nxfile = i;
				argv++;
				argc--;
			}
			continue;

		case 's':
			sflg++;
			continue;

		default:
			/* fprintf(stderr, "ncheck: bad flag %c\n", (*argv)[1]);*/
			printf(2, "ncheck: bad flag %c\n", (*argv)[1]);
			nerror++;
		}
		check(*argv);
	}
	return(nerror);
}

check(file)
char *file;
{
	register i, j;
	ino_t mino;

	fi = open(file, 0);
	if(fi < 0) {
		/* fprintf(stderr, "ncheck: cannot open %s\n", file); */
		printf(2, "ncheck: cannot open %s\n", file);
		nerror++;
		return;
	}
	nhent = 0;
	/* printf("%s:\n", file); */
	printf(1,"%s:\n", file);
	sync();
	bread((daddr_t)1, (char *)&sblock, sizeof(sblock));
	mino = (sblock.s_isize-2) * INOPB;
	ino = 0;
	for(i=2;; i+=NI) {
		if(ino >= mino)
			break;
		bread((daddr_t)i, (char *)itab, sizeof(itab));
		for(j=0; j<INOPB*NI; j++) {
			if(ino >= mino)
				break;
			ino++;
			pass1(&itab[j]);
		}
	}
	ilist[nxfile+1] = 0;
	ino = 0;
	for(i=2;; i+=NI) {
		if(ino >= mino)
			break;
		bread((daddr_t)i, (char *)itab, sizeof(itab));
		for(j=0; j<INOPB*NI; j++) {
			if(ino >= mino)
				break;
			ino++;
			pass2(&itab[j]);
		}
	}
	ino = 0;
	for(i=2;; i+=NI) {
		if(ino >= mino)
			break;
		bread((daddr_t)i, (char *)itab, sizeof(itab));
		for(j=0; j<INOPB*NI; j++) {
			if(ino >= mino)
				break;
			ino++;
			pass3(&itab[j]);
		}
	}
}

pass1(ip)
register struct dinode *ip;
{
	if((ip->di_mode & IFMT) != IFDIR) {
		if (sflg==0 || nxfile>=NB)
			return;
		if ((ip->di_mode&IFMT)==IFBLK || (ip->di_mode&IFMT)==IFCHR
		  || ip->di_mode&(ISUID|ISGID))
			ilist[nxfile++] = ino;
			return;
	}
	lookup(ino, 1);
}

pass2(ip)
register struct dinode *ip;
{
	struct direct dbuf[NDIR];
	long doff;
	struct direct *dp;
	register i, j;
	int k;
	struct htab *hp;
	daddr_t d;
	ino_t kno;

	if((ip->di_mode&IFMT) != IFDIR)
		return;
	l3tol(iaddr, ip->di_addr, NADDR);
	doff = 0;
	for(i=0;; i++) {
		if(doff >= ip->di_size)
			break;
		d = bmap(i);
		if(d == 0)
			break;
		bread(d, (char *)dbuf, sizeof(dbuf));
		for(j=0; j<NDIR; j++) {
			if(doff >= ip->di_size)
				break;
			doff += sizeof(struct direct);
			dp = dbuf+j;
			kno = dp->d_ino;
			if(kno == 0)
				continue;
			hp = lookup(kno, 0);
			if(hp == 0)
				continue;
			if(dotname(dp))
				continue;
			hp->h_pino = ino;
			for(k=0; k<DIRSIZ; k++)
				hp->h_name[k] = dp->d_name[k];
		}
	}
}

pass3(ip)
register struct dinode *ip;
{
	struct direct dbuf[NDIR];
	long doff;
	struct direct *dp;
	register i, j;
	int k;
	daddr_t d;
	ino_t kno;

	if((ip->di_mode&IFMT) != IFDIR)
		return;
	l3tol(iaddr, ip->di_addr, NADDR);
	doff = 0;
	for(i=0;; i++) {
		if(doff >= ip->di_size)
			break;
		d = bmap(i);
		if(d == 0)
			break;
		bread(d, (char *)dbuf, sizeof(dbuf));
		for(j=0; j<NDIR; j++) {
			if(doff >= ip->di_size)
				break;
			doff += sizeof(struct direct);
			dp = dbuf+j;
			kno = dp->d_ino;
			if(kno == 0)
				continue;
			if(aflg==0 && dotname(dp))
				continue;
			if(ilist[0] == 0)
				goto pr;
			for(k=0; ilist[k] != 0; k++)
				if(ilist[k] == kno)
					goto pr;
			continue;
		pr:
			/* printf("%u	", kno); */
			printf(1,"%u	", kno);
			pname(ino, 0);
			/* printf("/%.14s", dp->d_name); */
			strncpy(tmpbuf,dp->d_name,14);
			tmpbuf[14] = NULL;
			printf(1,"/%s", tmpbuf);
			if (lookup(kno, 0))
				/* printf("/."); */
				printf(1,"/.");
			/*printf("\n");*/
			printf(1,"\n");
		}
	}
}

dotname(dp)
register struct direct *dp;
{

	if (dp->d_name[0]=='.')
		if (dp->d_name[1]==0 || (dp->d_name[1]=='.' && dp->d_name[2]==0))
			return(1);
	return(0);
}

pname(i, lev)
ino_t i;
{
	register struct htab *hp;

	if (i==ROOTINO)
		return;
	if ((hp = lookup(i, 0)) == 0) {
		/*printf("???");*/
		printf(1,"???");
		return;
	}
	if (lev > 10) {
		/*printf("...");*/
		printf(1,"...");
		return;
	}
	pname(hp->h_pino, ++lev);
	/*printf("/%.14s", hp->h_name);*/
	strncpy(tmpbuf,hp->h_name,14);
	tmpbuf[14] = NULL;
	printf(1,"/%s", tmpbuf);
}

struct htab *
lookup(i, ef)
ino_t i;
{
	register struct htab *hp;

	for (hp = &htab[i%HSIZE]; hp->h_ino;) {
		if (hp->h_ino==i)
			return(hp);
		if (++hp >= &htab[HSIZE])
			hp = htab;
	}
	if (ef==0)
		return(0);
	if (++nhent >= HSIZE) {
		/*fprintf(stderr, "ncheck: out of core-- increase HSIZE\n");*/
		printf(2, "ncheck: out of core-- increase HSIZE\n");
		exit(1);
	}
	hp->h_ino = i;
	return(hp);
}

bread(bno, buf, cnt)
daddr_t bno;
char *buf;
{
	register i;

	lseek(fi, bno*BSIZE, 0);
	if (read(fi, buf, cnt) != cnt) {
		/*fprintf(stderr, "ncheck: read error %d\n", bno);*/
		printf(2, "ncheck: read error %d\n", bno);
		for(i=0; i<BSIZE; i++)
			buf[i] = 0;
	}
}

daddr_t
bmap(i)
{
	daddr_t ibuf[NINDIR];

	if(i < NADDR-3)
		return(iaddr[i]);
	i -= NADDR-3;
	if(i > NINDIR) {
		/*fprintf(stderr, "ncheck: %u - huge directory\n", ino);*/
		printf(2, "ncheck: %u - huge directory\n", ino);
		return((daddr_t)0);
	}
	bread(iaddr[NADDR-3], (char *)ibuf, sizeof(ibuf));
	return(ibuf[i]);
}
getchar()
{
	char c;
	if (read(0, &c, 1) < 0)
		return(-1);
	else
		return(c);
}
putchar(c,fd)
char c;
int fd;
{
	write(fd, &c, 1);
}

/*
 * Scaled down version of C Library printf.
 * Only %s %u %d (==%u) %o %x %D are recognized.
 */
/* VARARGS 1 */
printf(fd,fmt, x1)
register char *fmt;
unsigned x1;
int fd;
{
	register c;
	register unsigned int *adx;
	char *s;

	adx = &x1;
loop:
	while((c = *fmt++) != '%') {
		if(c == '\0')
			return;
		putchar(c,fd);
	}
	c = *fmt++;
	if(c == 'd' || c == 'u' || c == 'o' || c == 'x')
		printn((long)*adx, c=='o'? 8: (c=='x'? 16:10),fd);
	else if(c == 's') {
		s = (char *)*adx;
		while(c = *s++)
			putchar(c,fd);
	} else if (c == 'c') {
		putchar(*(char *)adx,fd);
	} else if (c == 'D') {
		printn(*(long *)adx, 10,fd);
		adx += (sizeof(long) / sizeof(int)) - 1;
	}
	adx++;
	goto loop;
}

/*
 * Print an unsigned integer in base b.
 */
printn(n, b,fd)
long n;
int fd;
{
	register long a;

	if (n<0) {	/* shouldn't happen */
		putchar('-',fd);
		n = -n;
	}
	if(a = n/b)
		printn(a, b,fd);
	putchar("0123456789ABCDEF"[(int)(n%b)],fd);
}