|
|
1.1 root 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) 6/5/85";
9: #endif not lint
10:
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.