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