⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 restor.c

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -