📄 dump.c
字号:
#define NI 16#define DIRPB (BSIZE/sizeof(struct direct))#include <stdio.h>#include <sys/param.h>#include <sys/inode.h>#include <sys/ino.h>#include <sys/fblk.h>#include <sys/filsys.h>#include <sys/dir.h>#include <dumprestor.h>#define MWORD(m,i) (m[(unsigned)(i-1)/MLEN])#define MBIT(i) (1<<((unsigned)(i-1)%MLEN))#define BIS(i,w) (MWORD(w,i) |= MBIT(i))#define BIC(i,w) (MWORD(w,i) &= ~MBIT(i))#define BIT(i,w) (MWORD(w,i) & MBIT(i))struct filsys sblock;struct dinode itab[INOPB*NI];short clrmap[MSIZ];short dirmap[MSIZ];short nodmap[MSIZ];char *disk;char *tape;char *increm;char incno;int uflag;int fi;int to;ino_t ino;int nsubdir;int ntape;int nadded;int dadded;int density = 160;char *ctime();char *prdate();long atol();int fi;long tsize;long esize;long asize;int mark();int add();int dump();int tapsrec();int dmpspc();int dsrch();int nullf();#define HOUR (60L*60L)#define DAY (24L*HOUR)#define YEAR (365L*DAY)main(argc, argv)char *argv[];{ char *arg; register i; time(&spcl.c_date); tsize = 2300L*12L*10L; tape = "/dev/rmt1"; disk = "/dev/rrp3"; increm = "/etc/ddate"; incno = '9'; uflag = 0; arg = "u"; if(argc > 1) { argv++; argc--; arg = *argv; } while(*arg) switch (*arg++) { case 'f': if(argc > 1) { argv++; argc--; tape = *argv; } break; case 'd': if (argc > 1) { argv++; argc--; density = atoi(*argv)/10; } break; case 's': if(argc > 1) { argv++; argc--; tsize = atol(*argv); tsize *= 12L*10L; } break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': incno = arg[-1]; break; case 'u': uflag++; break; default: printf("bad key '%c%'\n", arg[-1]); exit(1); } if(argc > 1) { argv++; argc--; disk = *argv; } getitime(); printf(" date = %s\n", prdate(spcl.c_date)); printf("dump date = %s\n", prdate(spcl.c_ddate)); printf("dumping %s to %s\n", disk, tape); fi = open(disk, 0); if(fi < 0) { printf("dump: cannot open %s\n", disk); exit(1); } otape(); printf("I\n"); esize = 0; CLR(clrmap); CLR(dirmap); CLR(nodmap); pass(mark, (short *)NULL); do { printf("II\n"); nadded = 0; pass(add, dirmap); } while(nadded); bmapest(clrmap); bmapest(nodmap); printf("estimated %ld tape blocks on %d tape(s)\n", esize, 0); printf("III\n"); bitmap(clrmap, TS_CLRI); pass(dump, dirmap); printf("IV\n"); pass(dump, nodmap); putitime(); printf("DONE\n"); spcl.c_type = TS_END; for(i=0; i<NTREC; i++) spclrec(); printf("%ld tape blocks on %d tape(s)\n", spcl.c_tapea, spcl.c_volume);}pass(fn, map)int (*fn)();short *map;{ register i, j; int bits; ino_t mino; daddr_t d; sync(); bread((daddr_t)1, (char *)&sblock, sizeof(sblock)); mino = (sblock.s_isize-2) * INOPB; ino = 0; for(i=2;; i+=NI) { if(ino >= mino) break; d = (unsigned)i; for(j=0; j<INOPB*NI; j++) { if(ino >= mino) break; if((ino % MLEN) == 0) { bits = ~0; if(map != NULL) bits = *map++; } ino++; if(bits & 1) { if(d != 0) { bread(d, (char *)itab, sizeof(itab)); d = 0; } (*fn)(&itab[j]); } bits >>= 1; } }}icat(ip, fn1, fn2)struct dinode *ip;int (*fn1)(), (*fn2)();{ register i; daddr_t d[NADDR]; l3tol(&d[0], &ip->di_addr[0], NADDR); (*fn2)(d, NADDR-3); for(i=0; i<NADDR; i++) { if(d[i] != 0) { if(i < NADDR-3) (*fn1)(d[i]); else indir(d[i], fn1, fn2, i-(NADDR-3)); } }}indir(d, fn1, fn2, n)daddr_t d;int (*fn1)(), (*fn2)();{ register i; daddr_t idblk[NINDIR]; bread(d, (char *)idblk, sizeof(idblk)); if(n <= 0) { spcl.c_type = TS_ADDR; (*fn2)(idblk, NINDIR); for(i=0; i<NINDIR; i++) { d = idblk[i]; if(d != 0) (*fn1)(d); } } else { n--; for(i=0; i<NINDIR; i++) { d = idblk[i]; if(d != 0) indir(d, fn1, fn2, n); } }}mark(ip)struct dinode *ip;{ register f; f = ip->di_mode & IFMT; if(f == 0) return; BIS(ino, clrmap); if(f == IFDIR) BIS(ino, dirmap); if(ip->di_mtime >= spcl.c_ddate || ip->di_ctime >= spcl.c_ddate) { BIS(ino, nodmap); if (f != IFREG) return; est(ip); }}add(ip)struct dinode *ip;{ if(BIT(ino, nodmap)) return; nsubdir = 0; dadded = 0; icat(ip, dsrch, nullf); if(dadded) { BIS(ino, nodmap); est(ip); nadded++; } if(nsubdir == 0) if(!BIT(ino, nodmap)) BIC(ino, dirmap);}dump(ip)struct dinode *ip;{ register i; if(ntape) { ntape = 0; bitmap(nodmap, TS_BITS); } BIC(ino, nodmap); spcl.c_dinode = *ip; spcl.c_type = TS_INODE; spcl.c_count = 0; i = ip->di_mode & IFMT; if(i != IFDIR && i != IFREG) { spclrec(); return; } icat(ip, tapsrec, dmpspc);}dmpspc(dp, n)daddr_t *dp;{ register i, t; spcl.c_count = n; for(i=0; i<n; i++) { t = 0; if(dp[i] != 0) t++; spcl.c_addr[i] = t; } spclrec();}bitmap(map, typ)short *map;{ register i, n; char *cp; n = -1; for(i=0; i<MSIZ; i++) if(map[i]) n = i; if(n < 0) return; spcl.c_type = typ; spcl.c_count = (n*sizeof(map[0]) + BSIZE)/BSIZE; spclrec(); cp = (char *)map; for(i=0; i<spcl.c_count; i++) { taprec(cp); cp += BSIZE; }}spclrec(){ register i, *ip, s; spcl.c_inumber = ino; spcl.c_magic = MAGIC; spcl.c_checksum = 0; ip = (int *)&spcl; s = 0; for(i=0; i<BSIZE/sizeof(*ip); i++) s += *ip++; spcl.c_checksum = CHECKSUM - s; taprec((char *)&spcl);}dsrch(d)daddr_t d;{ register char *cp; register i; register ino_t in; struct direct dblk[DIRPB]; if(dadded) return; bread(d, (char *)dblk, sizeof(dblk)); for(i=0; i<DIRPB; i++) { in = dblk[i].d_ino; if(in == 0) continue; cp = dblk[i].d_name; if(cp[0] == '.') { if(cp[1] == '\0') continue; if(cp[1] == '.' && cp[2] == '\0') continue; } if(BIT(in, nodmap)) { dadded++; return; } if(BIT(in, dirmap)) nsubdir++; }}nullf(){}bread(da, ba, c)daddr_t da;char *ba;{ register n; lseek(fi, da*512, 0); n = read(fi, ba, c); if(n != c) printf("asked %d; got %d\n", c, n);}CLR(map)register short *map;{ register n; n = MSIZ; do *map++ = 0; while(--n);}char tblock[NTREC][BSIZE];daddr_t tdaddr[NTREC];int trecno;taprec(dp)char *dp;{ register i; for(i=0; i<BSIZE; i++) tblock[trecno][i] = *dp++; tdaddr[trecno] = 0; trecno++; spcl.c_tapea++; if(trecno >= NTREC) flusht();}tapsrec(d)daddr_t d;{ if(d == 0) return; tdaddr[trecno] = d; trecno++; spcl.c_tapea++; if(trecno >= NTREC) flusht();}flusht(){ char place[100]; register i, si; daddr_t d; while(trecno < NTREC) tdaddr[trecno++] = 1;loop: d = 0; for(i=0; i<NTREC; i++) if(tdaddr[i] != 0) if(d == 0 || tdaddr[i] < d) { si = i; d = tdaddr[i]; } if(d != 0) { bread(d, tblock[si], BSIZE); tdaddr[si] = 0; goto loop; } trecno = 0; write(to, tblock[0], sizeof(tblock)); asize += sizeof(tblock)/density; asize += 7; if(asize > tsize) { close(to); printf("change tapes\n"); read(0, place, sizeof(place)); otape(); }}otape(){ to = creat(tape, 0666); if(to < 0) { printf("dump: cannot create %s\n", tape); exit(1); } asize = 0; ntape++; spcl.c_volume++; spcl.c_type = TS_TAPE; spclrec();}char *prdate(d)time_t d;{ char *p; if(d == 0) return("the epoch"); p = ctime(&d); p[24] = 0; return(p);}getitime(){ register i, df; struct idates idbuf; char *fname; fname = disk;l1: for(i=0; fname[i]; i++) if(fname[i] == '/') { fname += i+1; goto l1; } spcl.c_ddate = 0; df = open(increm, 0); if(df < 0) { printf("cannot open %s\n", increm); exit(1); }l2: i = read(df, (char *)&idbuf, sizeof(idbuf)); if(i != sizeof(idbuf)) { close(df); return; } for(i=0;; i++) { if(fname[i] != idbuf.id_name[i]) goto l2; if(fname[i] == '\0') break; } if(idbuf.id_incno >= incno) goto l2; if(idbuf.id_ddate <= spcl.c_ddate) goto l2; spcl.c_ddate = idbuf.id_ddate; goto l2;}putitime(){ register i, n, df; struct idates idbuf; char *fname; if(uflag == 0) return; fname = disk;l1: for(i=0; fname[i]; i++) if(fname[i] == '/') { fname += i+1; goto l1; } spcl.c_ddate = 0; df = open(increm, 2); if(df < 0) { printf("cannot open %s\n", increm); exit(1); } n = 0;l2: i = read(df, (char *)&idbuf, sizeof(idbuf)); if(i != sizeof(idbuf)) goto l3; n++; for(i=0;; i++) { if(fname[i] != idbuf.id_name[i]) goto l2; if(fname[i] == '\0') break; } if(idbuf.id_incno != incno) goto l2;l3: lseek(df, (long)n*sizeof(idbuf), 0); for(i=0;; i++) { idbuf.id_name[i] = fname[i]; if(fname[i] == '\0') break; } idbuf.id_incno = incno; idbuf.id_ddate = spcl.c_date; write(df, (char *)&idbuf, sizeof(idbuf)); close(df); printf("level %c dump on %s\n", incno, prdate(spcl.c_date));}est(ip)struct dinode *ip;{ long s; esize++; s = (ip->di_size + BSIZE-1) / BSIZE; esize += s; if(s > NADDR-3) { s -= NADDR-3; s = (s + (BSIZE/sizeof(daddr_t))-1) / (BSIZE/sizeof(daddr_t)); esize += s; }}bmapest(map)short *map;{ register i, n; n = -1; for(i=0; i<MSIZ; i++) if(map[i]) n = i; if(n < 0) return; esize++; esize += (n + (BSIZE/sizeof(short))-1) / (BSIZE/sizeof(short));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -