Commit | Line | Data |
---|---|---|
35fb2af5 BJ |
1 | static char *sccsid = "@(#)dumptraverse.c 1.1 (Berkeley) %G%"; |
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 |