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