add symbolic links
[unix-history] / usr / src / sbin / dump / traverse.c
CommitLineData
b45e25c0 1static char *sccsid = "@(#)traverse.c 1.6 (Berkeley) %G%";
35fb2af5 2
b6407c9d 3#include "dump.h"
b45e25c0 4#include <ndir.h>
35fb2af5
BJ
5
6pass(fn, map)
003a2a9e 7 int (*fn)();
b6407c9d 8 char *map;
35fb2af5 9{
003a2a9e 10 struct dinode *dp;
35fb2af5 11 int bits;
003a2a9e 12 ino_t maxino;
35fb2af5 13
b6407c9d 14 maxino = sblock->fs_ipg * sblock->fs_ncg - 1;
003a2a9e 15 for (ino = 0; ino < maxino; ) {
b6407c9d 16 if((ino % NBBY) == 0) {
003a2a9e
KM
17 bits = ~0;
18 if(map != NULL)
19 bits = *map++;
20 }
21 ino++;
22 if(bits & 1) {
23 dp = getino(ino);
24 (*fn)(dp);
35fb2af5 25 }
003a2a9e 26 bits >>= 1;
35fb2af5
BJ
27 }
28}
29
35fb2af5 30mark(ip)
1a350083 31 struct dinode *ip;
35fb2af5
BJ
32{
33 register f;
34
35 f = ip->di_mode & IFMT;
36 if(f == 0)
37 return;
38 BIS(ino, clrmap);
39 if(f == IFDIR)
40 BIS(ino, dirmap);
b6407c9d
KM
41 if ((ip->di_mtime >= spcl.c_ddate || ip->di_ctime >= spcl.c_ddate) &&
42 !BIT(ino, nodmap)) {
35fb2af5 43 BIS(ino, nodmap);
b6407c9d 44 if (f != IFREG && f != IFDIR) {
35fb2af5
BJ
45 esize += 1;
46 return;
47 }
48 est(ip);
49 }
50}
51
52add(ip)
b6407c9d 53 register struct dinode *ip;
35fb2af5 54{
b6407c9d 55 register int i;
35fb2af5
BJ
56
57 if(BIT(ino, nodmap))
58 return;
59 nsubdir = 0;
60 dadded = 0;
b6407c9d
KM
61 for (i = 0; i < NDADDR; i++) {
62 if (ip->di_db[i] != 0)
63 dsrch(ip->di_db[i], dblksize(sblock, ip, i));
64 }
65 for (i = 0; i < NIADDR; i++) {
66 if (ip->di_ib[i] != 0)
67 indir(ip->di_ib[i], i);
68 }
35fb2af5 69 if(dadded) {
35fb2af5 70 nadded++;
b6407c9d
KM
71 if (!BIT(ino, nodmap)) {
72 BIS(ino, nodmap);
73 est(ip);
74 }
35fb2af5
BJ
75 }
76 if(nsubdir == 0)
77 if(!BIT(ino, nodmap))
78 BIC(ino, dirmap);
79}
80
b6407c9d
KM
81indir(d, n)
82 daddr_t d;
83 int n;
84{
85 register i;
86 daddr_t idblk[MAXNINDIR];
87
88 bread(fsbtodb(sblock, d), (char *)idblk, sblock->fs_bsize);
89 if(n <= 0) {
90 for(i=0; i < NINDIR(sblock); i++) {
91 d = idblk[i];
92 if(d != 0)
93 dsrch(d, sblock->fs_bsize);
94 }
95 } else {
96 n--;
97 for(i=0; i < NINDIR(sblock); i++) {
98 d = idblk[i];
99 if(d != 0)
100 indir(d, n);
101 }
102 }
103}
104
35fb2af5 105dump(ip)
1a350083 106 struct dinode *ip;
35fb2af5 107{
1a350083
KM
108 register int i;
109 long size;
35fb2af5
BJ
110
111 if(newtape) {
112 newtape = 0;
113 bitmap(nodmap, TS_BITS);
114 }
115 BIC(ino, nodmap);
116 spcl.c_dinode = *ip;
117 spcl.c_type = TS_INODE;
118 spcl.c_count = 0;
119 i = ip->di_mode & IFMT;
1a350083 120 if ((i != IFDIR && i != IFREG) || ip->di_size == 0) {
35fb2af5
BJ
121 spclrec();
122 return;
123 }
b6407c9d
KM
124 if (ip->di_size > NDADDR * sblock->fs_bsize)
125 i = NDADDR * sblock->fs_frag;
1a350083 126 else
b6407c9d 127 i = howmany(ip->di_size, sblock->fs_fsize);
1a350083 128 blksout(&ip->di_db[0], i);
b6407c9d 129 size = ip->di_size - NDADDR * sblock->fs_bsize;
1a350083
KM
130 if (size <= 0)
131 return;
132 for (i = 0; i < NIADDR; i++) {
133 dmpindir(ip->di_ib[i], i, &size);
134 if (size <= 0)
135 return;
136 }
35fb2af5
BJ
137}
138
1a350083
KM
139dmpindir(blk, lvl, size)
140 daddr_t blk;
141 int lvl;
142 long *size;
35fb2af5 143{
1a350083 144 int i, cnt;
b6407c9d 145 daddr_t idblk[MAXNINDIR];
35fb2af5 146
1a350083 147 if (blk != 0)
b6407c9d 148 bread(fsbtodb(sblock, blk), (char *)idblk, sblock->fs_bsize);
1a350083 149 else
b6407c9d 150 blkclr(idblk, sblock->fs_bsize);
1a350083 151 if (lvl <= 0) {
b6407c9d
KM
152 if (*size < NINDIR(sblock) * sblock->fs_bsize)
153 cnt = howmany(*size, sblock->fs_fsize);
1a350083 154 else
b6407c9d
KM
155 cnt = NINDIR(sblock) * sblock->fs_frag;
156 *size -= NINDIR(sblock) * sblock->fs_bsize;
1a350083
KM
157 blksout(&idblk[0], cnt);
158 return;
159 }
160 lvl--;
b6407c9d 161 for (i = 0; i < NINDIR(sblock); i++) {
1a350083
KM
162 dmpindir(idblk[i], lvl, size);
163 if (*size <= 0)
164 return;
165 }
166}
167
168blksout(blkp, frags)
169 daddr_t *blkp;
170 int frags;
171{
b6407c9d 172 int i, j, count, blks, tbperdb;
1a350083 173
b6407c9d
KM
174 blks = frags * BLKING(sblock);
175 tbperdb = BLKING(sblock) * sblock->fs_frag;
1a350083
KM
176 for (i = 0; i < blks; i += TP_NINDIR) {
177 if (i + TP_NINDIR > blks)
178 count = blks;
179 else
180 count = i + TP_NINDIR;
181 for (j = i; j < count; j++)
b6407c9d 182 if (blkp[j / tbperdb] != 0)
1a350083
KM
183 spcl.c_addr[j - i] = 1;
184 else
185 spcl.c_addr[j - i] = 0;
186 spcl.c_count = count - i;
187 spclrec();
b6407c9d
KM
188 for (j = i; j < count; j += tbperdb)
189 if (blkp[j / tbperdb] != 0)
190 if (j + tbperdb <= count)
191 dmpblk(blkp[j / tbperdb],
192 sblock->fs_bsize);
1a350083 193 else
b6407c9d 194 dmpblk(blkp[j / tbperdb],
1a350083
KM
195 (count - j) * TP_BSIZE);
196 spcl.c_type = TS_ADDR;
35fb2af5 197 }
35fb2af5
BJ
198}
199
200bitmap(map, typ)
b6407c9d 201 char *map;
35fb2af5
BJ
202{
203 register i, n;
204 char *cp;
205
206 n = -1;
b6407c9d 207 for (i = 0; i < msiz; i++)
35fb2af5
BJ
208 if(map[i])
209 n = i;
b6407c9d 210 if (n < 0)
35fb2af5 211 return;
b6407c9d 212 n++;
35fb2af5 213 spcl.c_type = typ;
b6407c9d 214 spcl.c_count = howmany(n * sizeof(map[0]), TP_BSIZE);
35fb2af5 215 spclrec();
b6407c9d 216 for (i = 0, cp = map; i < spcl.c_count; i++, cp += TP_BSIZE)
35fb2af5 217 taprec(cp);
35fb2af5
BJ
218}
219
220spclrec()
221{
1a350083 222 register int s, i, *ip;
35fb2af5
BJ
223
224 spcl.c_inumber = ino;
225 spcl.c_magic = MAGIC;
226 spcl.c_checksum = 0;
227 ip = (int *)&spcl;
228 s = 0;
1a350083 229 for(i = 0; i < sizeof(union u_spcl)/sizeof(int); i++)
35fb2af5
BJ
230 s += *ip++;
231 spcl.c_checksum = CHECKSUM - s;
232 taprec((char *)&spcl);
233}
234
b6407c9d 235dsrch(d, size)
1a350083 236 daddr_t d;
b6407c9d 237 int size;
35fb2af5 238{
b45e25c0
KM
239 register struct direct *dp;
240 long loc;
241 char dblk[MAXBSIZE];
35fb2af5
BJ
242
243 if(dadded)
244 return;
b45e25c0
KM
245 bread(fsbtodb(sblock, d), dblk, size);
246 for (loc = 0; loc < size; ) {
247 dp = (struct direct *)(dblk + loc);
248 if (dp->d_reclen == 0)
249 break;
250 loc += dp->d_reclen;
251 if(dp->d_ino == 0)
35fb2af5 252 continue;
b45e25c0
KM
253 if(dp->d_name[0] == '.') {
254 if(dp->d_name[1] == '\0')
35fb2af5 255 continue;
b45e25c0 256 if(dp->d_name[1] == '.' && dp->d_name[2] == '\0')
35fb2af5
BJ
257 continue;
258 }
b45e25c0 259 if(BIT(dp->d_ino, nodmap)) {
35fb2af5
BJ
260 dadded++;
261 return;
262 }
b45e25c0 263 if(BIT(dp->d_ino, dirmap))
35fb2af5
BJ
264 nsubdir++;
265 }
266}
267
003a2a9e
KM
268struct dinode *
269getino(ino)
270 daddr_t ino;
271{
272 static daddr_t minino, maxino;
b6407c9d 273 static struct dinode itab[MAXINOPB];
003a2a9e
KM
274
275 if (ino >= minino && ino < maxino) {
276 return (&itab[ino - minino]);
277 }
6994bf5d 278 bread(fsbtodb(sblock, itod(sblock, ino)), itab, sblock->fs_bsize);
b6407c9d
KM
279 minino = ino - (ino % INOPB(sblock));
280 maxino = minino + INOPB(sblock);
003a2a9e
KM
281 return (&itab[ino - minino]);
282}
283
35fb2af5
BJ
284int breaderrors = 0;
285#define BREADEMAX 32
286
287bread(da, ba, c)
288 daddr_t da;
289 char *ba;
290 int c;
291{
292 register n;
293 register regc;
294
b6407c9d 295 if (lseek(fi, (long)(da * DEV_BSIZE), 0) < 0){
35fb2af5
BJ
296 msg("bread: lseek fails\n");
297 }
298 regc = c; /* put c someplace safe; it gets clobbered */
299 n = read(fi, ba, c);
b6407c9d 300 if (n != c || regc != c) {
35fb2af5
BJ
301 msg("(This should not happen)bread from %s [block %d]: c=0x%x, regc=0x%x, &c=0x%x, n=0x%x\n",
302 disk, da, c, regc, &c, n);
303#ifdef ERNIE
304 msg("Notify Robert Henry of this error.\n");
305#endif
306 if (++breaderrors > BREADEMAX){
307 msg("More than %d block read errors from %d\n",
308 BREADEMAX, disk);
309 broadcast("DUMP IS AILING!\n");
310 msg("This is an unrecoverable error.\n");
311 if (!query("Do you want to attempt to continue?")){
312 dumpabort();
313 /*NOTREACHED*/
314 } else
315 breaderrors = 0;
316 }
317 }
318}
319
1a350083
KM
320blkclr(cp, size)
321 char *cp;
322 long size;
323{
324 asm("movc5 $0,(r0),$0,8(ap),*4(ap)");
325}