1*22031Sdist /*
2*22031Sdist * Copyright (c) 1980 Regents of the University of California.
3*22031Sdist * All rights reserved. The Berkeley software License Agreement
4*22031Sdist * specifies the terms and conditions for redistribution.
5*22031Sdist */
6*22031Sdist
7*22031Sdist #ifndef lint
8*22031Sdist static char sccsid[] = "@(#)dumptraverse.c 5.1 (Berkeley) 06/05/85";
9*22031Sdist #endif not lint
10*22031Sdist
111426Sroot #include "dump.h"
121426Sroot
131426Sroot struct filsys sblock;
141426Sroot struct dinode itab[INOPB * NI];
151426Sroot
161426Sroot pass(fn, map)
171426Sroot int (*fn)();
181426Sroot short *map;
191426Sroot {
201426Sroot register i, j;
211426Sroot int bits;
221426Sroot ino_t mino;
231426Sroot daddr_t d;
241426Sroot
251426Sroot sync();
261426Sroot bread((daddr_t)1, (char *)&sblock, sizeof(sblock));
271426Sroot mino = (sblock.s_isize-2) * INOPB;
281426Sroot ino = 0;
291426Sroot for(i=2;; i+=NI) {
301426Sroot if(ino >= mino)
311426Sroot break;
321426Sroot d = (unsigned)i;
331426Sroot for(j=0; j<INOPB*NI; j++) {
341426Sroot if(ino >= mino)
351426Sroot break;
361426Sroot if((ino % MLEN) == 0) {
371426Sroot bits = ~0;
381426Sroot if(map != NULL)
391426Sroot bits = *map++;
401426Sroot }
411426Sroot ino++;
421426Sroot if(bits & 1) {
431426Sroot if(d != 0) {
441426Sroot bread(d, (char *)itab, sizeof(itab));
451426Sroot d = 0;
461426Sroot }
471426Sroot (*fn)(&itab[j]);
481426Sroot }
491426Sroot bits >>= 1;
501426Sroot }
511426Sroot }
521426Sroot }
531426Sroot
541426Sroot icat(ip, fn1, fn2)
551426Sroot struct dinode *ip;
561426Sroot int (*fn1)(), (*fn2)();
571426Sroot {
581426Sroot register i;
591426Sroot daddr_t d[NADDR];
601426Sroot
611426Sroot l3tol(&d[0], &ip->di_addr[0], NADDR);
621426Sroot (*fn2)(d, NADDR-3);
631426Sroot for(i=0; i<NADDR; i++) {
641426Sroot if(d[i] != 0) {
651426Sroot if(i < NADDR-3)
661426Sroot (*fn1)(d[i]); else
671426Sroot indir(d[i], fn1, fn2, i-(NADDR-3));
681426Sroot }
691426Sroot }
701426Sroot }
711426Sroot
indir(d,fn1,fn2,n)721426Sroot indir(d, fn1, fn2, n)
731426Sroot daddr_t d;
741426Sroot int (*fn1)(), (*fn2)();
751426Sroot {
761426Sroot register i;
771426Sroot daddr_t idblk[NINDIR];
781426Sroot
791426Sroot bread(d, (char *)idblk, sizeof(idblk));
801426Sroot if(n <= 0) {
811426Sroot spcl.c_type = TS_ADDR;
821426Sroot (*fn2)(idblk, NINDIR);
831426Sroot for(i=0; i<NINDIR; i++) {
841426Sroot d = idblk[i];
851426Sroot if(d != 0)
861426Sroot (*fn1)(d);
871426Sroot }
881426Sroot } else {
891426Sroot n--;
901426Sroot for(i=0; i<NINDIR; i++) {
911426Sroot d = idblk[i];
921426Sroot if(d != 0)
931426Sroot indir(d, fn1, fn2, n);
941426Sroot }
951426Sroot }
961426Sroot }
971426Sroot
981426Sroot mark(ip)
991426Sroot struct dinode *ip;
1001426Sroot {
1011426Sroot register f;
1021426Sroot
1031426Sroot f = ip->di_mode & IFMT;
1041426Sroot if(f == 0)
1051426Sroot return;
1061426Sroot BIS(ino, clrmap);
1071426Sroot if(f == IFDIR)
1081426Sroot BIS(ino, dirmap);
1091426Sroot if(ip->di_mtime >= spcl.c_ddate ||
1101426Sroot ip->di_ctime >= spcl.c_ddate) {
1111426Sroot BIS(ino, nodmap);
1121426Sroot if (f != IFREG){
1131426Sroot esize += 1;
1141426Sroot return;
1151426Sroot }
1161426Sroot est(ip);
1171426Sroot }
1181426Sroot }
1191426Sroot
1201426Sroot add(ip)
1211426Sroot struct dinode *ip;
1221426Sroot {
1231426Sroot
1241426Sroot if(BIT(ino, nodmap))
1251426Sroot return;
1261426Sroot nsubdir = 0;
1271426Sroot dadded = 0;
1281426Sroot icat(ip, dsrch, nullf);
1291426Sroot if(dadded) {
1301426Sroot BIS(ino, nodmap);
1311426Sroot est(ip);
1321426Sroot nadded++;
1331426Sroot }
1341426Sroot if(nsubdir == 0)
1351426Sroot if(!BIT(ino, nodmap))
1361426Sroot BIC(ino, dirmap);
1371426Sroot }
1381426Sroot
1391426Sroot dump(ip)
1401426Sroot struct dinode *ip;
1411426Sroot {
1421426Sroot register i;
1431426Sroot
1441426Sroot if(newtape) {
1451426Sroot newtape = 0;
1461426Sroot bitmap(nodmap, TS_BITS);
1471426Sroot }
1481426Sroot BIC(ino, nodmap);
1491426Sroot spcl.c_dinode = *ip;
1501426Sroot spcl.c_type = TS_INODE;
1511426Sroot spcl.c_count = 0;
1521426Sroot i = ip->di_mode & IFMT;
1531426Sroot if(i != IFDIR && i != IFREG) {
1541426Sroot spclrec();
1551426Sroot return;
1561426Sroot }
1571426Sroot icat(ip, tapsrec, dmpspc);
1581426Sroot }
1591426Sroot
dmpspc(dp,n)1601426Sroot dmpspc(dp, n)
1611426Sroot daddr_t *dp;
1621426Sroot {
1631426Sroot register i, t;
1641426Sroot
1651426Sroot spcl.c_count = n;
1661426Sroot for(i=0; i<n; i++) {
1671426Sroot t = 0;
1681426Sroot if(dp[i] != 0)
1691426Sroot t++;
1701426Sroot spcl.c_addr[i] = t;
1711426Sroot }
1721426Sroot spclrec();
1731426Sroot }
1741426Sroot
bitmap(map,typ)1751426Sroot bitmap(map, typ)
1761426Sroot short *map;
1771426Sroot {
1781426Sroot register i, n;
1791426Sroot char *cp;
1801426Sroot
1811426Sroot n = -1;
1821426Sroot for(i=0; i<MSIZ; i++)
1831426Sroot if(map[i])
1841426Sroot n = i;
1851426Sroot if(n < 0)
1861426Sroot return;
1871426Sroot spcl.c_type = typ;
1881426Sroot spcl.c_count = (n*sizeof(map[0]) + BSIZE)/BSIZE;
1891426Sroot spclrec();
1901426Sroot cp = (char *)map;
1911426Sroot for(i=0; i<spcl.c_count; i++) {
1921426Sroot taprec(cp);
1931426Sroot cp += BSIZE;
1941426Sroot }
1951426Sroot }
1961426Sroot
spclrec()1971426Sroot spclrec()
1981426Sroot {
1991426Sroot register i, *ip, s;
2001426Sroot
2011426Sroot spcl.c_inumber = ino;
2021426Sroot spcl.c_magic = MAGIC;
2031426Sroot spcl.c_checksum = 0;
2041426Sroot ip = (int *)&spcl;
2051426Sroot s = 0;
2061426Sroot for(i=0; i<BSIZE/sizeof(*ip); i++)
2071426Sroot s += *ip++;
2081426Sroot spcl.c_checksum = CHECKSUM - s;
2091426Sroot taprec((char *)&spcl);
2101426Sroot }
2111426Sroot
dsrch(d)2121426Sroot dsrch(d)
2131426Sroot daddr_t d;
2141426Sroot {
2151426Sroot register char *cp;
2161426Sroot register i;
2171426Sroot register ino_t in;
2181426Sroot struct direct dblk[DIRPB];
2191426Sroot
2201426Sroot if(dadded)
2211426Sroot return;
2221426Sroot bread(d, (char *)dblk, sizeof(dblk));
2231426Sroot for(i=0; i<DIRPB; i++) {
2241426Sroot in = dblk[i].d_ino;
2251426Sroot if(in == 0)
2261426Sroot continue;
2271426Sroot cp = dblk[i].d_name;
2281426Sroot if(cp[0] == '.') {
2291426Sroot if(cp[1] == '\0')
2301426Sroot continue;
2311426Sroot if(cp[1] == '.' && cp[2] == '\0')
2321426Sroot continue;
2331426Sroot }
2341426Sroot if(BIT(in, nodmap)) {
2351426Sroot dadded++;
2361426Sroot return;
2371426Sroot }
2381426Sroot if(BIT(in, dirmap))
2391426Sroot nsubdir++;
2401426Sroot }
2411426Sroot }
2421426Sroot
nullf()2431426Sroot nullf()
2441426Sroot {
2451426Sroot }
2461426Sroot
2471426Sroot int breaderrors = 0;
2481426Sroot #define BREADEMAX 32
2491426Sroot
bread(da,ba,c)2501426Sroot bread(da, ba, c)
2511426Sroot daddr_t da;
2521426Sroot char *ba;
2531426Sroot int c;
2541426Sroot {
2551426Sroot register n;
2561426Sroot register regc;
2571426Sroot
2581426Sroot if (lseek(fi, (long)(da*BSIZE), 0) < 0){
2591426Sroot msg("bread: lseek fails\n");
2601426Sroot }
2611426Sroot regc = c; /* put c someplace safe; it gets clobbered */
2621426Sroot n = read(fi, ba, c);
2631426Sroot if(n != c || regc != c){
2641426Sroot msg("(This should not happen)bread from %s [block %d]: c=0x%x, regc=0x%x, &c=0x%x, n=0x%x\n",
2651426Sroot disk, da, c, regc, &c, n);
2661426Sroot #ifdef ERNIE
2671426Sroot msg("Notify Robert Henry of this error.\n");
2681426Sroot #endif
2691426Sroot if (++breaderrors > BREADEMAX){
2701426Sroot msg("More than %d block read errors from %d\n",
2711426Sroot BREADEMAX, disk);
2721426Sroot broadcast("DUMP IS AILING!\n");
2731426Sroot msg("This is an unrecoverable error.\n");
2741426Sroot if (!query("Do you want to attempt to continue?")){
2751426Sroot dumpabort();
2761426Sroot /*NOTREACHED*/
2771426Sroot } else
2781426Sroot breaderrors = 0;
2791426Sroot }
2801426Sroot }
2811426Sroot }
2821426Sroot
CLR(map)2831426Sroot CLR(map)
2841426Sroot register short *map;
2851426Sroot {
2861426Sroot register n;
2871426Sroot
2881426Sroot n = MSIZ;
2891426Sroot do
2901426Sroot *map++ = 0;
2911426Sroot while(--n);
2921426Sroot }
2931426Sroot
294