xref: /csrg-svn/sbin/dump/traverse.c (revision 1426)
1*1426Sroot static	char *sccsid = "@(#)traverse.c	1.1 (Berkeley) 10/13/80";
2*1426Sroot #include "dump.h"
3*1426Sroot 
4*1426Sroot struct	filsys	sblock;
5*1426Sroot struct	dinode	itab[INOPB * NI];
6*1426Sroot 
7*1426Sroot pass(fn, map)
8*1426Sroot int (*fn)();
9*1426Sroot short *map;
10*1426Sroot {
11*1426Sroot 	register i, j;
12*1426Sroot 	int bits;
13*1426Sroot 	ino_t mino;
14*1426Sroot 	daddr_t d;
15*1426Sroot 
16*1426Sroot 	sync();
17*1426Sroot 	bread((daddr_t)1, (char *)&sblock, sizeof(sblock));
18*1426Sroot 	mino = (sblock.s_isize-2) * INOPB;
19*1426Sroot 	ino = 0;
20*1426Sroot 	for(i=2;; i+=NI) {
21*1426Sroot 		if(ino >= mino)
22*1426Sroot 			break;
23*1426Sroot 		d = (unsigned)i;
24*1426Sroot 		for(j=0; j<INOPB*NI; j++) {
25*1426Sroot 			if(ino >= mino)
26*1426Sroot 				break;
27*1426Sroot 			if((ino % MLEN) == 0) {
28*1426Sroot 				bits = ~0;
29*1426Sroot 				if(map != NULL)
30*1426Sroot 					bits = *map++;
31*1426Sroot 			}
32*1426Sroot 			ino++;
33*1426Sroot 			if(bits & 1) {
34*1426Sroot 				if(d != 0) {
35*1426Sroot 					bread(d, (char *)itab, sizeof(itab));
36*1426Sroot 					d = 0;
37*1426Sroot 				}
38*1426Sroot 				(*fn)(&itab[j]);
39*1426Sroot 			}
40*1426Sroot 			bits >>= 1;
41*1426Sroot 		}
42*1426Sroot 	}
43*1426Sroot }
44*1426Sroot 
45*1426Sroot icat(ip, fn1, fn2)
46*1426Sroot struct	dinode	*ip;
47*1426Sroot int (*fn1)(), (*fn2)();
48*1426Sroot {
49*1426Sroot 	register i;
50*1426Sroot 	daddr_t d[NADDR];
51*1426Sroot 
52*1426Sroot 	l3tol(&d[0], &ip->di_addr[0], NADDR);
53*1426Sroot 	(*fn2)(d, NADDR-3);
54*1426Sroot 	for(i=0; i<NADDR; i++) {
55*1426Sroot 		if(d[i] != 0) {
56*1426Sroot 			if(i < NADDR-3)
57*1426Sroot 				(*fn1)(d[i]); else
58*1426Sroot 				indir(d[i], fn1, fn2, i-(NADDR-3));
59*1426Sroot 		}
60*1426Sroot 	}
61*1426Sroot }
62*1426Sroot 
63*1426Sroot indir(d, fn1, fn2, n)
64*1426Sroot daddr_t d;
65*1426Sroot int (*fn1)(), (*fn2)();
66*1426Sroot {
67*1426Sroot 	register i;
68*1426Sroot 	daddr_t	idblk[NINDIR];
69*1426Sroot 
70*1426Sroot 	bread(d, (char *)idblk, sizeof(idblk));
71*1426Sroot 	if(n <= 0) {
72*1426Sroot 		spcl.c_type = TS_ADDR;
73*1426Sroot 		(*fn2)(idblk, NINDIR);
74*1426Sroot 		for(i=0; i<NINDIR; i++) {
75*1426Sroot 			d = idblk[i];
76*1426Sroot 			if(d != 0)
77*1426Sroot 				(*fn1)(d);
78*1426Sroot 		}
79*1426Sroot 	} else {
80*1426Sroot 		n--;
81*1426Sroot 		for(i=0; i<NINDIR; i++) {
82*1426Sroot 			d = idblk[i];
83*1426Sroot 			if(d != 0)
84*1426Sroot 				indir(d, fn1, fn2, n);
85*1426Sroot 		}
86*1426Sroot 	}
87*1426Sroot }
88*1426Sroot 
89*1426Sroot mark(ip)
90*1426Sroot struct dinode *ip;
91*1426Sroot {
92*1426Sroot 	register f;
93*1426Sroot 
94*1426Sroot 	f = ip->di_mode & IFMT;
95*1426Sroot 	if(f == 0)
96*1426Sroot 		return;
97*1426Sroot 	BIS(ino, clrmap);
98*1426Sroot 	if(f == IFDIR)
99*1426Sroot 		BIS(ino, dirmap);
100*1426Sroot 	if(ip->di_mtime >= spcl.c_ddate ||
101*1426Sroot 	   ip->di_ctime >= spcl.c_ddate) {
102*1426Sroot 		BIS(ino, nodmap);
103*1426Sroot 		if (f != IFREG){
104*1426Sroot 			esize += 1;
105*1426Sroot 			return;
106*1426Sroot 		}
107*1426Sroot 		est(ip);
108*1426Sroot 	}
109*1426Sroot }
110*1426Sroot 
111*1426Sroot add(ip)
112*1426Sroot struct dinode *ip;
113*1426Sroot {
114*1426Sroot 
115*1426Sroot 	if(BIT(ino, nodmap))
116*1426Sroot 		return;
117*1426Sroot 	nsubdir = 0;
118*1426Sroot 	dadded = 0;
119*1426Sroot 	icat(ip, dsrch, nullf);
120*1426Sroot 	if(dadded) {
121*1426Sroot 		BIS(ino, nodmap);
122*1426Sroot 		est(ip);
123*1426Sroot 		nadded++;
124*1426Sroot 	}
125*1426Sroot 	if(nsubdir == 0)
126*1426Sroot 		if(!BIT(ino, nodmap))
127*1426Sroot 			BIC(ino, dirmap);
128*1426Sroot }
129*1426Sroot 
130*1426Sroot dump(ip)
131*1426Sroot struct dinode *ip;
132*1426Sroot {
133*1426Sroot 	register i;
134*1426Sroot 
135*1426Sroot 	if(newtape) {
136*1426Sroot 		newtape = 0;
137*1426Sroot 		bitmap(nodmap, TS_BITS);
138*1426Sroot 	}
139*1426Sroot 	BIC(ino, nodmap);
140*1426Sroot 	spcl.c_dinode = *ip;
141*1426Sroot 	spcl.c_type = TS_INODE;
142*1426Sroot 	spcl.c_count = 0;
143*1426Sroot 	i = ip->di_mode & IFMT;
144*1426Sroot 	if(i != IFDIR && i != IFREG) {
145*1426Sroot 		spclrec();
146*1426Sroot 		return;
147*1426Sroot 	}
148*1426Sroot 	icat(ip, tapsrec, dmpspc);
149*1426Sroot }
150*1426Sroot 
151*1426Sroot dmpspc(dp, n)
152*1426Sroot daddr_t *dp;
153*1426Sroot {
154*1426Sroot 	register i, t;
155*1426Sroot 
156*1426Sroot 	spcl.c_count = n;
157*1426Sroot 	for(i=0; i<n; i++) {
158*1426Sroot 		t = 0;
159*1426Sroot 		if(dp[i] != 0)
160*1426Sroot 			t++;
161*1426Sroot 		spcl.c_addr[i] = t;
162*1426Sroot 	}
163*1426Sroot 	spclrec();
164*1426Sroot }
165*1426Sroot 
166*1426Sroot bitmap(map, typ)
167*1426Sroot short *map;
168*1426Sroot {
169*1426Sroot 	register i, n;
170*1426Sroot 	char *cp;
171*1426Sroot 
172*1426Sroot 	n = -1;
173*1426Sroot 	for(i=0; i<MSIZ; i++)
174*1426Sroot 		if(map[i])
175*1426Sroot 			n = i;
176*1426Sroot 	if(n < 0)
177*1426Sroot 		return;
178*1426Sroot 	spcl.c_type = typ;
179*1426Sroot 	spcl.c_count = (n*sizeof(map[0]) + BSIZE)/BSIZE;
180*1426Sroot 	spclrec();
181*1426Sroot 	cp = (char *)map;
182*1426Sroot 	for(i=0; i<spcl.c_count; i++) {
183*1426Sroot 		taprec(cp);
184*1426Sroot 		cp += BSIZE;
185*1426Sroot 	}
186*1426Sroot }
187*1426Sroot 
188*1426Sroot spclrec()
189*1426Sroot {
190*1426Sroot 	register i, *ip, s;
191*1426Sroot 
192*1426Sroot 	spcl.c_inumber = ino;
193*1426Sroot 	spcl.c_magic = MAGIC;
194*1426Sroot 	spcl.c_checksum = 0;
195*1426Sroot 	ip = (int *)&spcl;
196*1426Sroot 	s = 0;
197*1426Sroot 	for(i=0; i<BSIZE/sizeof(*ip); i++)
198*1426Sroot 		s += *ip++;
199*1426Sroot 	spcl.c_checksum = CHECKSUM - s;
200*1426Sroot 	taprec((char *)&spcl);
201*1426Sroot }
202*1426Sroot 
203*1426Sroot dsrch(d)
204*1426Sroot daddr_t d;
205*1426Sroot {
206*1426Sroot 	register char *cp;
207*1426Sroot 	register i;
208*1426Sroot 	register ino_t in;
209*1426Sroot 	struct direct dblk[DIRPB];
210*1426Sroot 
211*1426Sroot 	if(dadded)
212*1426Sroot 		return;
213*1426Sroot 	bread(d, (char *)dblk, sizeof(dblk));
214*1426Sroot 	for(i=0; i<DIRPB; i++) {
215*1426Sroot 		in = dblk[i].d_ino;
216*1426Sroot 		if(in == 0)
217*1426Sroot 			continue;
218*1426Sroot 		cp = dblk[i].d_name;
219*1426Sroot 		if(cp[0] == '.') {
220*1426Sroot 			if(cp[1] == '\0')
221*1426Sroot 				continue;
222*1426Sroot 			if(cp[1] == '.' && cp[2] == '\0')
223*1426Sroot 				continue;
224*1426Sroot 		}
225*1426Sroot 		if(BIT(in, nodmap)) {
226*1426Sroot 			dadded++;
227*1426Sroot 			return;
228*1426Sroot 		}
229*1426Sroot 		if(BIT(in, dirmap))
230*1426Sroot 			nsubdir++;
231*1426Sroot 	}
232*1426Sroot }
233*1426Sroot 
234*1426Sroot nullf()
235*1426Sroot {
236*1426Sroot }
237*1426Sroot 
238*1426Sroot int	breaderrors = 0;
239*1426Sroot #define	BREADEMAX 32
240*1426Sroot 
241*1426Sroot bread(da, ba, c)
242*1426Sroot 	daddr_t da;
243*1426Sroot 	char *ba;
244*1426Sroot 	int	c;
245*1426Sroot {
246*1426Sroot 	register n;
247*1426Sroot 	register	regc;
248*1426Sroot 
249*1426Sroot 	if (lseek(fi, (long)(da*BSIZE), 0) < 0){
250*1426Sroot 		msg("bread: lseek fails\n");
251*1426Sroot 	}
252*1426Sroot 	regc = c;	/* put c someplace safe; it gets clobbered */
253*1426Sroot 	n = read(fi, ba, c);
254*1426Sroot 	if(n != c || regc != c){
255*1426Sroot 		msg("(This should not happen)bread from %s [block %d]: c=0x%x, regc=0x%x, &c=0x%x, n=0x%x\n",
256*1426Sroot 			disk, da, c, regc, &c, n);
257*1426Sroot #ifdef ERNIE
258*1426Sroot 		msg("Notify Robert Henry of this error.\n");
259*1426Sroot #endif
260*1426Sroot 		if (++breaderrors > BREADEMAX){
261*1426Sroot 			msg("More than %d block read errors from %d\n",
262*1426Sroot 				BREADEMAX, disk);
263*1426Sroot 			broadcast("DUMP IS AILING!\n");
264*1426Sroot 			msg("This is an unrecoverable error.\n");
265*1426Sroot 			if (!query("Do you want to attempt to continue?")){
266*1426Sroot 				dumpabort();
267*1426Sroot 				/*NOTREACHED*/
268*1426Sroot 			} else
269*1426Sroot 				breaderrors = 0;
270*1426Sroot 		}
271*1426Sroot 	}
272*1426Sroot }
273*1426Sroot 
274*1426Sroot CLR(map)
275*1426Sroot register short *map;
276*1426Sroot {
277*1426Sroot 	register n;
278*1426Sroot 
279*1426Sroot 	n = MSIZ;
280*1426Sroot 	do
281*1426Sroot 		*map++ = 0;
282*1426Sroot 	while(--n);
283*1426Sroot }
284*1426Sroot 
285