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