xref: /csrg-svn/old/dump.4.1/dumptraverse.c (revision 22031)
1*22031Sdist /*
2*22031Sdist  * Copyright (c) 1980 Regents of the University of California.
3*22031Sdist  * All rights reserved.  The Berkeley software License Agreement
4*22031Sdist  * specifies the terms and conditions for redistribution.
5*22031Sdist  */
6*22031Sdist 
7*22031Sdist #ifndef lint
8*22031Sdist static char sccsid[] = "@(#)dumptraverse.c	5.1 (Berkeley) 06/05/85";
9*22031Sdist #endif not lint
10*22031Sdist 
111426Sroot #include "dump.h"
121426Sroot 
131426Sroot struct	filsys	sblock;
141426Sroot struct	dinode	itab[INOPB * NI];
151426Sroot 
161426Sroot pass(fn, map)
171426Sroot int (*fn)();
181426Sroot short *map;
191426Sroot {
201426Sroot 	register i, j;
211426Sroot 	int bits;
221426Sroot 	ino_t mino;
231426Sroot 	daddr_t d;
241426Sroot 
251426Sroot 	sync();
261426Sroot 	bread((daddr_t)1, (char *)&sblock, sizeof(sblock));
271426Sroot 	mino = (sblock.s_isize-2) * INOPB;
281426Sroot 	ino = 0;
291426Sroot 	for(i=2;; i+=NI) {
301426Sroot 		if(ino >= mino)
311426Sroot 			break;
321426Sroot 		d = (unsigned)i;
331426Sroot 		for(j=0; j<INOPB*NI; j++) {
341426Sroot 			if(ino >= mino)
351426Sroot 				break;
361426Sroot 			if((ino % MLEN) == 0) {
371426Sroot 				bits = ~0;
381426Sroot 				if(map != NULL)
391426Sroot 					bits = *map++;
401426Sroot 			}
411426Sroot 			ino++;
421426Sroot 			if(bits & 1) {
431426Sroot 				if(d != 0) {
441426Sroot 					bread(d, (char *)itab, sizeof(itab));
451426Sroot 					d = 0;
461426Sroot 				}
471426Sroot 				(*fn)(&itab[j]);
481426Sroot 			}
491426Sroot 			bits >>= 1;
501426Sroot 		}
511426Sroot 	}
521426Sroot }
531426Sroot 
541426Sroot icat(ip, fn1, fn2)
551426Sroot struct	dinode	*ip;
561426Sroot int (*fn1)(), (*fn2)();
571426Sroot {
581426Sroot 	register i;
591426Sroot 	daddr_t d[NADDR];
601426Sroot 
611426Sroot 	l3tol(&d[0], &ip->di_addr[0], NADDR);
621426Sroot 	(*fn2)(d, NADDR-3);
631426Sroot 	for(i=0; i<NADDR; i++) {
641426Sroot 		if(d[i] != 0) {
651426Sroot 			if(i < NADDR-3)
661426Sroot 				(*fn1)(d[i]); else
671426Sroot 				indir(d[i], fn1, fn2, i-(NADDR-3));
681426Sroot 		}
691426Sroot 	}
701426Sroot }
711426Sroot 
indir(d,fn1,fn2,n)721426Sroot indir(d, fn1, fn2, n)
731426Sroot daddr_t d;
741426Sroot int (*fn1)(), (*fn2)();
751426Sroot {
761426Sroot 	register i;
771426Sroot 	daddr_t	idblk[NINDIR];
781426Sroot 
791426Sroot 	bread(d, (char *)idblk, sizeof(idblk));
801426Sroot 	if(n <= 0) {
811426Sroot 		spcl.c_type = TS_ADDR;
821426Sroot 		(*fn2)(idblk, NINDIR);
831426Sroot 		for(i=0; i<NINDIR; i++) {
841426Sroot 			d = idblk[i];
851426Sroot 			if(d != 0)
861426Sroot 				(*fn1)(d);
871426Sroot 		}
881426Sroot 	} else {
891426Sroot 		n--;
901426Sroot 		for(i=0; i<NINDIR; i++) {
911426Sroot 			d = idblk[i];
921426Sroot 			if(d != 0)
931426Sroot 				indir(d, fn1, fn2, n);
941426Sroot 		}
951426Sroot 	}
961426Sroot }
971426Sroot 
981426Sroot mark(ip)
991426Sroot struct dinode *ip;
1001426Sroot {
1011426Sroot 	register f;
1021426Sroot 
1031426Sroot 	f = ip->di_mode & IFMT;
1041426Sroot 	if(f == 0)
1051426Sroot 		return;
1061426Sroot 	BIS(ino, clrmap);
1071426Sroot 	if(f == IFDIR)
1081426Sroot 		BIS(ino, dirmap);
1091426Sroot 	if(ip->di_mtime >= spcl.c_ddate ||
1101426Sroot 	   ip->di_ctime >= spcl.c_ddate) {
1111426Sroot 		BIS(ino, nodmap);
1121426Sroot 		if (f != IFREG){
1131426Sroot 			esize += 1;
1141426Sroot 			return;
1151426Sroot 		}
1161426Sroot 		est(ip);
1171426Sroot 	}
1181426Sroot }
1191426Sroot 
1201426Sroot add(ip)
1211426Sroot struct dinode *ip;
1221426Sroot {
1231426Sroot 
1241426Sroot 	if(BIT(ino, nodmap))
1251426Sroot 		return;
1261426Sroot 	nsubdir = 0;
1271426Sroot 	dadded = 0;
1281426Sroot 	icat(ip, dsrch, nullf);
1291426Sroot 	if(dadded) {
1301426Sroot 		BIS(ino, nodmap);
1311426Sroot 		est(ip);
1321426Sroot 		nadded++;
1331426Sroot 	}
1341426Sroot 	if(nsubdir == 0)
1351426Sroot 		if(!BIT(ino, nodmap))
1361426Sroot 			BIC(ino, dirmap);
1371426Sroot }
1381426Sroot 
1391426Sroot dump(ip)
1401426Sroot struct dinode *ip;
1411426Sroot {
1421426Sroot 	register i;
1431426Sroot 
1441426Sroot 	if(newtape) {
1451426Sroot 		newtape = 0;
1461426Sroot 		bitmap(nodmap, TS_BITS);
1471426Sroot 	}
1481426Sroot 	BIC(ino, nodmap);
1491426Sroot 	spcl.c_dinode = *ip;
1501426Sroot 	spcl.c_type = TS_INODE;
1511426Sroot 	spcl.c_count = 0;
1521426Sroot 	i = ip->di_mode & IFMT;
1531426Sroot 	if(i != IFDIR && i != IFREG) {
1541426Sroot 		spclrec();
1551426Sroot 		return;
1561426Sroot 	}
1571426Sroot 	icat(ip, tapsrec, dmpspc);
1581426Sroot }
1591426Sroot 
dmpspc(dp,n)1601426Sroot dmpspc(dp, n)
1611426Sroot daddr_t *dp;
1621426Sroot {
1631426Sroot 	register i, t;
1641426Sroot 
1651426Sroot 	spcl.c_count = n;
1661426Sroot 	for(i=0; i<n; i++) {
1671426Sroot 		t = 0;
1681426Sroot 		if(dp[i] != 0)
1691426Sroot 			t++;
1701426Sroot 		spcl.c_addr[i] = t;
1711426Sroot 	}
1721426Sroot 	spclrec();
1731426Sroot }
1741426Sroot 
bitmap(map,typ)1751426Sroot bitmap(map, typ)
1761426Sroot short *map;
1771426Sroot {
1781426Sroot 	register i, n;
1791426Sroot 	char *cp;
1801426Sroot 
1811426Sroot 	n = -1;
1821426Sroot 	for(i=0; i<MSIZ; i++)
1831426Sroot 		if(map[i])
1841426Sroot 			n = i;
1851426Sroot 	if(n < 0)
1861426Sroot 		return;
1871426Sroot 	spcl.c_type = typ;
1881426Sroot 	spcl.c_count = (n*sizeof(map[0]) + BSIZE)/BSIZE;
1891426Sroot 	spclrec();
1901426Sroot 	cp = (char *)map;
1911426Sroot 	for(i=0; i<spcl.c_count; i++) {
1921426Sroot 		taprec(cp);
1931426Sroot 		cp += BSIZE;
1941426Sroot 	}
1951426Sroot }
1961426Sroot 
spclrec()1971426Sroot spclrec()
1981426Sroot {
1991426Sroot 	register i, *ip, s;
2001426Sroot 
2011426Sroot 	spcl.c_inumber = ino;
2021426Sroot 	spcl.c_magic = MAGIC;
2031426Sroot 	spcl.c_checksum = 0;
2041426Sroot 	ip = (int *)&spcl;
2051426Sroot 	s = 0;
2061426Sroot 	for(i=0; i<BSIZE/sizeof(*ip); i++)
2071426Sroot 		s += *ip++;
2081426Sroot 	spcl.c_checksum = CHECKSUM - s;
2091426Sroot 	taprec((char *)&spcl);
2101426Sroot }
2111426Sroot 
dsrch(d)2121426Sroot dsrch(d)
2131426Sroot daddr_t d;
2141426Sroot {
2151426Sroot 	register char *cp;
2161426Sroot 	register i;
2171426Sroot 	register ino_t in;
2181426Sroot 	struct direct dblk[DIRPB];
2191426Sroot 
2201426Sroot 	if(dadded)
2211426Sroot 		return;
2221426Sroot 	bread(d, (char *)dblk, sizeof(dblk));
2231426Sroot 	for(i=0; i<DIRPB; i++) {
2241426Sroot 		in = dblk[i].d_ino;
2251426Sroot 		if(in == 0)
2261426Sroot 			continue;
2271426Sroot 		cp = dblk[i].d_name;
2281426Sroot 		if(cp[0] == '.') {
2291426Sroot 			if(cp[1] == '\0')
2301426Sroot 				continue;
2311426Sroot 			if(cp[1] == '.' && cp[2] == '\0')
2321426Sroot 				continue;
2331426Sroot 		}
2341426Sroot 		if(BIT(in, nodmap)) {
2351426Sroot 			dadded++;
2361426Sroot 			return;
2371426Sroot 		}
2381426Sroot 		if(BIT(in, dirmap))
2391426Sroot 			nsubdir++;
2401426Sroot 	}
2411426Sroot }
2421426Sroot 
nullf()2431426Sroot nullf()
2441426Sroot {
2451426Sroot }
2461426Sroot 
2471426Sroot int	breaderrors = 0;
2481426Sroot #define	BREADEMAX 32
2491426Sroot 
bread(da,ba,c)2501426Sroot bread(da, ba, c)
2511426Sroot 	daddr_t da;
2521426Sroot 	char *ba;
2531426Sroot 	int	c;
2541426Sroot {
2551426Sroot 	register n;
2561426Sroot 	register	regc;
2571426Sroot 
2581426Sroot 	if (lseek(fi, (long)(da*BSIZE), 0) < 0){
2591426Sroot 		msg("bread: lseek fails\n");
2601426Sroot 	}
2611426Sroot 	regc = c;	/* put c someplace safe; it gets clobbered */
2621426Sroot 	n = read(fi, ba, c);
2631426Sroot 	if(n != c || regc != c){
2641426Sroot 		msg("(This should not happen)bread from %s [block %d]: c=0x%x, regc=0x%x, &c=0x%x, n=0x%x\n",
2651426Sroot 			disk, da, c, regc, &c, n);
2661426Sroot #ifdef ERNIE
2671426Sroot 		msg("Notify Robert Henry of this error.\n");
2681426Sroot #endif
2691426Sroot 		if (++breaderrors > BREADEMAX){
2701426Sroot 			msg("More than %d block read errors from %d\n",
2711426Sroot 				BREADEMAX, disk);
2721426Sroot 			broadcast("DUMP IS AILING!\n");
2731426Sroot 			msg("This is an unrecoverable error.\n");
2741426Sroot 			if (!query("Do you want to attempt to continue?")){
2751426Sroot 				dumpabort();
2761426Sroot 				/*NOTREACHED*/
2771426Sroot 			} else
2781426Sroot 				breaderrors = 0;
2791426Sroot 		}
2801426Sroot 	}
2811426Sroot }
2821426Sroot 
CLR(map)2831426Sroot CLR(map)
2841426Sroot register short *map;
2851426Sroot {
2861426Sroot 	register n;
2871426Sroot 
2881426Sroot 	n = MSIZ;
2891426Sroot 	do
2901426Sroot 		*map++ = 0;
2911426Sroot 	while(--n);
2921426Sroot }
2931426Sroot 
294