restor from "standard" (ie 1K file system) dump tapes
[unix-history] / usr / src / sbin / dump / traverse.c
CommitLineData
f5bba473 1static char *sccsid = "@(#)traverse.c 1.3 (Berkeley) %G%";
35fb2af5
BJ
2#include "dump.h"
3
003a2a9e 4struct fs sblock;
35fb2af5
BJ
5
6pass(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
36icat(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
53indir(d, fn1, fn2, n)
54daddr_t d;
55int (*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
79mark(ip)
80struct 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
101add(ip)
102struct 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
120dump(ip)
121struct 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
141dmpspc(dp, n)
142daddr_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
156bitmap(map, typ)
157short *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
178spclrec()
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
193dsrch(d)
194daddr_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
224nullf()
225{
226}
227
003a2a9e
KM
228struct dinode *
229getino(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
244int breaderrors = 0;
245#define BREADEMAX 32
246
247bread(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
280CLR(map)
281register short *map;
282{
283 register n;
284
285 n = MSIZ;
286 do
287 *map++ = 0;
288 while(--n);
289}
290