xref: /csrg-svn/sbin/dump/traverse.c (revision 4702)
1*4702Smckusic static	char *sccsid = "@(#)traverse.c	1.2 (Berkeley) 10/31/81";
21426Sroot #include "dump.h"
31426Sroot 
4*4702Smckusic struct	fs	sblock;
51426Sroot 
61426Sroot pass(fn, map)
7*4702Smckusic 	int (*fn)();
8*4702Smckusic 	short *map;
91426Sroot {
10*4702Smckusic 	struct dinode *dp;
111426Sroot 	int bits;
12*4702Smckusic 	ino_t maxino;
131426Sroot 
141426Sroot 	sync();
15*4702Smckusic 	bread(SBLOCK, &sblock, sizeof sblock);
16*4702Smckusic 	if (sblock.fs_magic != FS_MAGIC) {
17*4702Smckusic 		msg("bad sblock magic number\n");
18*4702Smckusic 		dumpabort();
19*4702Smckusic 	}
20*4702Smckusic 	maxino = sblock.fs_ipg * sblock.fs_ncg;
21*4702Smckusic 	for (ino = 0; ino < maxino; ) {
22*4702Smckusic 		if((ino % MLEN) == 0) {
23*4702Smckusic 			bits = ~0;
24*4702Smckusic 			if(map != NULL)
25*4702Smckusic 				bits = *map++;
261426Sroot 		}
27*4702Smckusic 		ino++;
28*4702Smckusic 		if(bits & 1) {
29*4702Smckusic 			dp = getino(ino);
30*4702Smckusic 			(*fn)(dp);
31*4702Smckusic 		}
32*4702Smckusic 		bits >>= 1;
331426Sroot 	}
341426Sroot }
351426Sroot 
36*4702Smckusic icat(dp, fn1, fn2)
37*4702Smckusic 	register struct	dinode	*dp;
38*4702Smckusic 	int (*fn1)(), (*fn2)();
391426Sroot {
40*4702Smckusic 	register int i;
411426Sroot 
42*4702Smckusic 	(*fn2)(dp->di_db, NDADDR);
43*4702Smckusic 	for (i = 0; i < NDADDR; i++) {
44*4702Smckusic 		if (dp->di_db[i] != 0)
45*4702Smckusic 			(*fn1)(dp->di_db[i]);
461426Sroot 	}
47*4702Smckusic 	for (i = 0; i < NIADDR; i++) {
48*4702Smckusic 		if (dp->di_ib[i] != 0)
49*4702Smckusic 			indir(dp->di_ib[i], fn1, fn2, i);
50*4702Smckusic 	}
511426Sroot }
521426Sroot 
531426Sroot indir(d, fn1, fn2, n)
541426Sroot daddr_t d;
551426Sroot int (*fn1)(), (*fn2)();
561426Sroot {
571426Sroot 	register i;
581426Sroot 	daddr_t	idblk[NINDIR];
591426Sroot 
601426Sroot 	bread(d, (char *)idblk, sizeof(idblk));
611426Sroot 	if(n <= 0) {
621426Sroot 		spcl.c_type = TS_ADDR;
631426Sroot 		(*fn2)(idblk, NINDIR);
641426Sroot 		for(i=0; i<NINDIR; i++) {
651426Sroot 			d = idblk[i];
661426Sroot 			if(d != 0)
671426Sroot 				(*fn1)(d);
681426Sroot 		}
691426Sroot 	} else {
701426Sroot 		n--;
711426Sroot 		for(i=0; i<NINDIR; i++) {
721426Sroot 			d = idblk[i];
731426Sroot 			if(d != 0)
741426Sroot 				indir(d, fn1, fn2, n);
751426Sroot 		}
761426Sroot 	}
771426Sroot }
781426Sroot 
791426Sroot mark(ip)
801426Sroot struct dinode *ip;
811426Sroot {
821426Sroot 	register f;
831426Sroot 
841426Sroot 	f = ip->di_mode & IFMT;
851426Sroot 	if(f == 0)
861426Sroot 		return;
871426Sroot 	BIS(ino, clrmap);
881426Sroot 	if(f == IFDIR)
891426Sroot 		BIS(ino, dirmap);
901426Sroot 	if(ip->di_mtime >= spcl.c_ddate ||
911426Sroot 	   ip->di_ctime >= spcl.c_ddate) {
921426Sroot 		BIS(ino, nodmap);
931426Sroot 		if (f != IFREG){
941426Sroot 			esize += 1;
951426Sroot 			return;
961426Sroot 		}
971426Sroot 		est(ip);
981426Sroot 	}
991426Sroot }
1001426Sroot 
1011426Sroot add(ip)
1021426Sroot struct dinode *ip;
1031426Sroot {
1041426Sroot 
1051426Sroot 	if(BIT(ino, nodmap))
1061426Sroot 		return;
1071426Sroot 	nsubdir = 0;
1081426Sroot 	dadded = 0;
1091426Sroot 	icat(ip, dsrch, nullf);
1101426Sroot 	if(dadded) {
1111426Sroot 		BIS(ino, nodmap);
1121426Sroot 		est(ip);
1131426Sroot 		nadded++;
1141426Sroot 	}
1151426Sroot 	if(nsubdir == 0)
1161426Sroot 		if(!BIT(ino, nodmap))
1171426Sroot 			BIC(ino, dirmap);
1181426Sroot }
1191426Sroot 
1201426Sroot dump(ip)
1211426Sroot struct dinode *ip;
1221426Sroot {
1231426Sroot 	register i;
1241426Sroot 
1251426Sroot 	if(newtape) {
1261426Sroot 		newtape = 0;
1271426Sroot 		bitmap(nodmap, TS_BITS);
1281426Sroot 	}
1291426Sroot 	BIC(ino, nodmap);
1301426Sroot 	spcl.c_dinode = *ip;
1311426Sroot 	spcl.c_type = TS_INODE;
1321426Sroot 	spcl.c_count = 0;
1331426Sroot 	i = ip->di_mode & IFMT;
1341426Sroot 	if(i != IFDIR && i != IFREG) {
1351426Sroot 		spclrec();
1361426Sroot 		return;
1371426Sroot 	}
1381426Sroot 	icat(ip, tapsrec, dmpspc);
1391426Sroot }
1401426Sroot 
1411426Sroot dmpspc(dp, n)
1421426Sroot daddr_t *dp;
1431426Sroot {
1441426Sroot 	register i, t;
1451426Sroot 
1461426Sroot 	spcl.c_count = n;
1471426Sroot 	for(i=0; i<n; i++) {
1481426Sroot 		t = 0;
1491426Sroot 		if(dp[i] != 0)
1501426Sroot 			t++;
1511426Sroot 		spcl.c_addr[i] = t;
1521426Sroot 	}
1531426Sroot 	spclrec();
1541426Sroot }
1551426Sroot 
1561426Sroot bitmap(map, typ)
1571426Sroot short *map;
1581426Sroot {
1591426Sroot 	register i, n;
1601426Sroot 	char *cp;
1611426Sroot 
1621426Sroot 	n = -1;
1631426Sroot 	for(i=0; i<MSIZ; i++)
1641426Sroot 		if(map[i])
1651426Sroot 			n = i;
1661426Sroot 	if(n < 0)
1671426Sroot 		return;
1681426Sroot 	spcl.c_type = typ;
1691426Sroot 	spcl.c_count = (n*sizeof(map[0]) + BSIZE)/BSIZE;
1701426Sroot 	spclrec();
1711426Sroot 	cp = (char *)map;
1721426Sroot 	for(i=0; i<spcl.c_count; i++) {
1731426Sroot 		taprec(cp);
1741426Sroot 		cp += BSIZE;
1751426Sroot 	}
1761426Sroot }
1771426Sroot 
1781426Sroot spclrec()
1791426Sroot {
1801426Sroot 	register i, *ip, s;
1811426Sroot 
1821426Sroot 	spcl.c_inumber = ino;
1831426Sroot 	spcl.c_magic = MAGIC;
1841426Sroot 	spcl.c_checksum = 0;
1851426Sroot 	ip = (int *)&spcl;
1861426Sroot 	s = 0;
1871426Sroot 	for(i=0; i<BSIZE/sizeof(*ip); i++)
1881426Sroot 		s += *ip++;
1891426Sroot 	spcl.c_checksum = CHECKSUM - s;
1901426Sroot 	taprec((char *)&spcl);
1911426Sroot }
1921426Sroot 
1931426Sroot dsrch(d)
1941426Sroot daddr_t d;
1951426Sroot {
1961426Sroot 	register char *cp;
1971426Sroot 	register i;
1981426Sroot 	register ino_t in;
1991426Sroot 	struct direct dblk[DIRPB];
2001426Sroot 
2011426Sroot 	if(dadded)
2021426Sroot 		return;
2031426Sroot 	bread(d, (char *)dblk, sizeof(dblk));
2041426Sroot 	for(i=0; i<DIRPB; i++) {
2051426Sroot 		in = dblk[i].d_ino;
2061426Sroot 		if(in == 0)
2071426Sroot 			continue;
2081426Sroot 		cp = dblk[i].d_name;
2091426Sroot 		if(cp[0] == '.') {
2101426Sroot 			if(cp[1] == '\0')
2111426Sroot 				continue;
2121426Sroot 			if(cp[1] == '.' && cp[2] == '\0')
2131426Sroot 				continue;
2141426Sroot 		}
2151426Sroot 		if(BIT(in, nodmap)) {
2161426Sroot 			dadded++;
2171426Sroot 			return;
2181426Sroot 		}
2191426Sroot 		if(BIT(in, dirmap))
2201426Sroot 			nsubdir++;
2211426Sroot 	}
2221426Sroot }
2231426Sroot 
2241426Sroot nullf()
2251426Sroot {
2261426Sroot }
2271426Sroot 
228*4702Smckusic struct dinode *
229*4702Smckusic getino(ino)
230*4702Smckusic 	daddr_t ino;
231*4702Smckusic {
232*4702Smckusic 	static daddr_t minino, maxino;
233*4702Smckusic 	static struct dinode itab[INOPB];
234*4702Smckusic 
235*4702Smckusic 	if (ino >= minino && ino < maxino) {
236*4702Smckusic 		return (&itab[ino - minino]);
237*4702Smckusic 	}
238*4702Smckusic 	bread(itod(ino, &sblock), itab, BSIZE);
239*4702Smckusic 	minino = ino - (ino % INOPB);
240*4702Smckusic 	maxino = minino + INOPB;
241*4702Smckusic 	return (&itab[ino - minino]);
242*4702Smckusic }
243*4702Smckusic 
2441426Sroot int	breaderrors = 0;
2451426Sroot #define	BREADEMAX 32
2461426Sroot 
2471426Sroot bread(da, ba, c)
2481426Sroot 	daddr_t da;
2491426Sroot 	char *ba;
2501426Sroot 	int	c;
2511426Sroot {
2521426Sroot 	register n;
2531426Sroot 	register	regc;
2541426Sroot 
255*4702Smckusic 	if (lseek(fi, (long)(da*FSIZE), 0) < 0){
2561426Sroot 		msg("bread: lseek fails\n");
2571426Sroot 	}
2581426Sroot 	regc = c;	/* put c someplace safe; it gets clobbered */
2591426Sroot 	n = read(fi, ba, c);
2601426Sroot 	if(n != c || regc != c){
2611426Sroot 		msg("(This should not happen)bread from %s [block %d]: c=0x%x, regc=0x%x, &c=0x%x, n=0x%x\n",
2621426Sroot 			disk, da, c, regc, &c, n);
2631426Sroot #ifdef ERNIE
2641426Sroot 		msg("Notify Robert Henry of this error.\n");
2651426Sroot #endif
2661426Sroot 		if (++breaderrors > BREADEMAX){
2671426Sroot 			msg("More than %d block read errors from %d\n",
2681426Sroot 				BREADEMAX, disk);
2691426Sroot 			broadcast("DUMP IS AILING!\n");
2701426Sroot 			msg("This is an unrecoverable error.\n");
2711426Sroot 			if (!query("Do you want to attempt to continue?")){
2721426Sroot 				dumpabort();
2731426Sroot 				/*NOTREACHED*/
2741426Sroot 			} else
2751426Sroot 				breaderrors = 0;
2761426Sroot 		}
2771426Sroot 	}
2781426Sroot }
2791426Sroot 
2801426Sroot CLR(map)
2811426Sroot register short *map;
2821426Sroot {
2831426Sroot 	register n;
2841426Sroot 
2851426Sroot 	n = MSIZ;
2861426Sroot 	do
2871426Sroot 		*map++ = 0;
2881426Sroot 	while(--n);
2891426Sroot }
2901426Sroot 
291