📄 restor.c
字号:
#define MAXINO 3000#define BITS 8#define MAXXTR 60#define NCACHE 3#ifndef STANDALONE#include <stdio.h>#include <signal.h>#endif#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;int fi;ino_t ino, maxi, curino;int mt;char tapename[] = "/dev/rmt1";char *magtape = tapename;#ifdef STANDALONEchar mbuf[50];#endif#ifndef STANDALONEdaddr_t seekpt;int df, ofile;char dirfile[] = "rstXXXXXX";struct { ino_t t_ino; daddr_t t_seekpt;} inotab[MAXINO];int ipos;#define ONTAPE 1#define XTRACTD 2#define XINUSE 4struct xtrlist { ino_t x_ino; char x_flags;} xtrlist[MAXXTR];char name[12];char drblock[BSIZE];int bpt;#endifint eflag;int volno = 1;struct dinode tino, dino;daddr_t taddr[NADDR];daddr_t curbno;short dumpmap[MSIZ];short clrimap[MSIZ];int bct = NTREC+1;char tbf[NTREC*BSIZE];struct cache { daddr_t c_bno; int c_time; char c_block[BSIZE];} cache[NCACHE];int curcache;main(argc, argv)char *argv[];{ register char *cp; char command; int done();#ifndef STANDALONE mktemp(dirfile); if (argc < 2) {usage: printf("Usage: restor x file file..., restor r filesys, or restor t\n"); exit(1); } argv++; argc -= 2; for (cp = *argv++; *cp; cp++) { switch (*cp) { case '-': break; case 'f': magtape = *argv++; argc--; break; case 'r': case 'R': case 't': case 'x': command = *cp; break; default: printf("Bad key character %c\n", *cp); goto usage; } } if (command == 'x') { if (signal(SIGINT, done) == SIG_IGN) signal(SIGINT, SIG_IGN); if (signal(SIGTERM, done) == SIG_IGN) signal(SIGTERM, SIG_IGN); df = creat(dirfile, 0666); if (df < 0) { printf("restor: %s - cannot create directory temporary\n", dirfile); exit(1); } close(df); df = open(dirfile, 2); } doit(command, argc, argv); if (command == 'x') unlink(dirfile); exit(0);#else magtape = "tape"; doit('r', 1, 0);#endif}doit(command, argc, argv)char command;int argc;char *argv[];{ extern char *ctime(); register i, k; ino_t d;#ifndef STANDALONE int xtrfile(), skip();#endif int rstrfile(), rstrskip(); struct dinode *ip, *ip1;#ifndef STANDALONE if ((mt = open(magtape, 0)) < 0) { printf("%s: cannot open tape\n", magtape); exit(1); }#else do { printf("Tape? "); gets(mbuf); mt = open(mbuf, 0); } while (mt == -1); magtape = mbuf;#endif switch(command) {#ifndef STANDALONE case 't': if (readhdr(&spcl) == 0) { printf("Tape is not a dump tape\n"); exit(1); } printf("Dump date: %s", ctime(&spcl.c_date)); printf("Dumped from: %s", ctime(&spcl.c_ddate)); return; case 'x': if (readhdr(&spcl) == 0) { printf("Tape is not a dump tape\n"); exit(1); } if (checkvol(&spcl, 1) == 0) { printf("Tape is not volume 1 of the dump\n"); exit(1); } pass1(); /* This sets the various maps on the way by */ i = 0; while (i < MAXXTR-1 && argc--) { if ((d = psearch(*argv)) == 0 || BIT(d, dumpmap) == 0) { printf("%s: not on the tape\n", *argv++); continue; } xtrlist[i].x_ino = d; xtrlist[i].x_flags |= XINUSE; printf("%s: inode %u\n", *argv, d); argv++; i++; }newvol: flsht(); close(mt);getvol: printf("Mount desired tape volume: Specify volume #: "); if (gets(tbf) == NULL) return; volno = atoi(tbf); if (volno <= 0) { printf("Volume numbers are positive numerics\n"); goto getvol; } mt = open(magtape, 0); if (readhdr(&spcl) == 0) { printf("tape is not dump tape\n"); goto newvol; } if (checkvol(&spcl, volno) == 0) { printf("Wrong volume (%d)\n", spcl.c_volume); goto newvol; }rbits: while (gethead(&spcl) == 0) ; if (checktype(&spcl, TS_INODE) == 1) { printf("Can't find inode mask!\n"); goto newvol; } if (checktype(&spcl, TS_BITS) == 0) goto rbits; readbits(dumpmap); i = 0; for (k = 0; xtrlist[k].x_flags; k++) { if (BIT(xtrlist[k].x_ino, dumpmap)) { xtrlist[k].x_flags |= ONTAPE; i++; } } while (i > 0) {again: if (ishead(&spcl) == 0) while(gethead(&spcl) == 0) ; if (checktype(&spcl, TS_END) == 1) { printf("end of tape\n");checkdone: for (k = 0; xtrlist[k].x_flags; k++) if ((xtrlist[k].x_flags&XTRACTD) == 0) goto newvol; return; } if (checktype(&spcl, TS_INODE) == 0) { gethead(&spcl); goto again; } d = spcl.c_inumber; for (k = 0; xtrlist[k].x_flags; k++) { if (d == xtrlist[k].x_ino) { printf("extract file %u\n", xtrlist[k].x_ino); sprintf(name, "%u", xtrlist[k].x_ino); if ((ofile = creat(name, 0666)) < 0) { printf("%s: cannot create file\n", name); i--; continue; } chown(name, spcl.c_dinode.di_uid, spcl.c_dinode.di_gid); getfile(ino, xtrfile, skip, spcl.c_dinode.di_size); i--; xtrlist[k].x_flags |= XTRACTD; close(ofile); goto done; } } gethead(&spcl);done: ; } goto checkdone;#endif case 'r': case 'R':#ifndef STANDALONE if ((fi = open(*argv, 2)) < 0) { printf("%s: cannot open\n", *argv); exit(1); }#else do { char charbuf[50]; printf("Disk? "); gets(charbuf); fi = open(charbuf, 2); } while (fi == -1);#endif#ifndef STANDALONE if (command == 'R') { printf("Enter starting volume number: "); if (gets(tbf) == EOF) { volno = 1; printf("\n"); } else volno = atoi(tbf); } else#endif volno = 1; printf("Last chance before scribbling on %s. ",#ifdef STANDALONE "disk");#else *argv);#endif while (getchar() != '\n'); dread((daddr_t)1, (char *)&sblock, sizeof(sblock)); maxi = (sblock.s_isize-2)*INOPB; if (readhdr(&spcl) == 0) { printf("Missing volume record\n"); exit(1); } if (checkvol(&spcl, volno) == 0) { printf("Tape is not volume %d\n", volno); exit(1); } gethead(&spcl); for (;;) {ragain: if (ishead(&spcl) == 0) { printf("Missing header block\n"); while (gethead(&spcl) == 0) ; eflag++; } if (checktype(&spcl, TS_END) == 1) { printf("End of tape\n"); close(mt); dwrite( (daddr_t) 1, (char *) &sblock); return; } if (checktype(&spcl, TS_CLRI) == 1) { readbits(clrimap); for (ino = 1; ino <= maxi; ino++) if (BIT(ino, clrimap) == 0) { getdino(ino, &tino); if (tino.di_mode == 0) continue; itrunc(&tino); clri(&tino); putdino(ino, &tino); } dwrite( (daddr_t) 1, (char *) &sblock); goto ragain; } if (checktype(&spcl, TS_BITS) == 1) { readbits(dumpmap); goto ragain; } if (checktype(&spcl, TS_INODE) == 0) { printf("Unknown header type\n"); eflag++; gethead(&spcl); goto ragain; } ino = spcl.c_inumber; if (eflag) printf("Resynced at inode %u\n", ino); eflag = 0; if (ino > maxi) { printf("%u: ilist too small\n", ino); gethead(&spcl); goto ragain; } dino = spcl.c_dinode; getdino(ino, &tino); curbno = 0; itrunc(&tino); clri(&tino); for (i = 0; i < NADDR; i++) taddr[i] = 0; l3tol(taddr, dino.di_addr, 1); getfile(ino, rstrfile, rstrskip, dino.di_size); ip = &tino; ltol3(ip->di_addr, taddr, NADDR); ip1 = &dino; ip->di_mode = ip1->di_mode; ip->di_nlink = ip1->di_nlink; ip->di_uid = ip1->di_uid; ip->di_gid = ip1->di_gid; ip->di_size = ip1->di_size; ip->di_atime = ip1->di_atime; ip->di_mtime = ip1->di_mtime; ip->di_ctime = ip1->di_ctime; putdino(ino, &tino); } }}/* * Read the tape, bulding up a directory structure for extraction * by name */#ifndef STANDALONEpass1(){ register i; struct dinode *ip; int putdir(), null(); while (gethead(&spcl) == 0) { printf("Can't find directory header!\n"); } for (;;) { if (checktype(&spcl, TS_BITS) == 1) { readbits(dumpmap); continue; } if (checktype(&spcl, TS_CLRI) == 1) { readbits(clrimap); continue; } if (checktype(&spcl, TS_INODE) == 0) {finish: flsh(); close(mt); return; } ip = &spcl.c_dinode; i = ip->di_mode & IFMT; if (i != IFDIR) { goto finish; } inotab[ipos].t_ino = spcl.c_inumber; inotab[ipos++].t_seekpt = seekpt; getfile(spcl.c_inumber, putdir, null, spcl.c_dinode.di_size); putent("\000\000/"); }}#endif/* * Do the file extraction, calling the supplied functions * with the blocks */getfile(n, f1, f2, size)ino_t n;int (*f2)(), (*f1)();long size;{ register i; struct spcl addrblock; char buf[BSIZE]; addrblock = spcl; curino = n; goto start; for (;;) { if (gethead(&addrblock) == 0) { printf("Missing address (header) block\n"); goto eloop; } if (checktype(&addrblock, TS_ADDR) == 0) { spcl = addrblock; curino = 0; return; }start: for (i = 0; i < addrblock.c_count; i++) { if (addrblock.c_addr[i]) { readtape(buf); (*f1)(buf, size > BSIZE ? (long) BSIZE : size); } else { clearbuf(buf); (*f2)(buf, size > BSIZE ? (long) BSIZE : size); } if ((size -= BSIZE) <= 0) {eloop: while (gethead(&spcl) == 0) ; if (checktype(&spcl, TS_ADDR) == 1) goto eloop; curino = 0; return; } } }}/* * Do the tape i\/o, dealling with volume changes * etc.. */readtape(b)char *b;{ register i; struct spcl tmpbuf; if (bct >= NTREC) { for (i = 0; i < NTREC; i++) ((struct spcl *)&tbf[i*BSIZE])->c_magic = 0; bct = 0; if ((i = read(mt, tbf, NTREC*BSIZE)) < 0) { printf("Tape read error: inode %u\n", curino); eflag++; for (i = 0; i < NTREC; i++) clearbuf(&tbf[i*BSIZE]); } if (i == 0) { bct = NTREC + 1; volno++;loop: flsht(); close(mt); printf("Mount volume %d\n", volno); while (getchar() != '\n') ; if ((mt = open(magtape, 0)) == -1) { printf("Cannot open tape!\n"); goto loop; } if (readhdr(&tmpbuf) == 0) { printf("Not a dump tape.Try again\n"); goto loop; } if (checkvol(&tmpbuf, volno) == 0) { printf("Wrong tape. Try again\n"); goto loop; } readtape(b); return; } } copy(&tbf[(bct++*BSIZE)], b, BSIZE);}flsht(){ bct = NTREC+1;}copy(f, t, s)register char *f, *t;{ register i; i = s; do *t++ = *f++; while (--i);}clearbuf(cp)register char *cp;{ register i; i = BSIZE; do *cp++ = 0; while (--i);}/* * Put and get the directory entries from the compressed * directory file */#ifndef STANDALONEputent(cp)char *cp;{ register i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -