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

📄 tar.c

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/dir.h>#include <signal.h>char	*sprintf();char	*strcat();daddr_t	bsrch();#define TBLOCK	512#define NBLOCK	20#define NAMSIZ	100union hblock {	char dummy[TBLOCK];	struct header {		char name[NAMSIZ];		char mode[8];		char uid[8];		char gid[8];		char size[12];		char mtime[12];		char chksum[8];		char linkflag;		char linkname[NAMSIZ];	} dbuf;} dblock, tbuf[NBLOCK];struct linkbuf {	ino_t	inum;	dev_t	devnum;	int	count;	char	pathname[NAMSIZ];	struct	linkbuf *nextp;} *ihead;struct stat stbuf;int	rflag, xflag, vflag, tflag, mt, cflag, mflag;int	term, chksum, wflag, recno, first, linkerrok;int	freemem = 1;int	nblock = 1;daddr_t	low;daddr_t	high;FILE	*tfile;char	tname[] = "/tmp/tarXXXXXX";char	*usefile;char	magtape[]	= "/dev/mt1";char	*malloc();main(argc, argv)int	argc;char	*argv[];{	char *cp;	int onintr(), onquit(), onhup(), onterm();	if (argc < 2)		usage();	tfile = NULL;	usefile =  magtape;	argv[argc] = 0;	argv++;	for (cp = *argv++; *cp; cp++) 		switch(*cp) {		case 'f':			usefile = *argv++;			if (nblock == 1)				nblock = 0;			break;		case 'c':			cflag++;			rflag++;			break;		case 'u':			mktemp(tname);			if ((tfile = fopen(tname, "w")) == NULL) {				fprintf(stderr, "Tar: cannot create temporary file (%s)\n", tname);				done(1);			}			fprintf(tfile, "!!!!!/!/!/!/!/!/!/! 000\n");			/* FALL THROUGH */		case 'r':			rflag++;			if (nblock != 1 && cflag == 0) {noupdate:				fprintf(stderr, "Tar: Blocked tapes cannot be updated (yet)\n");				done(1);			}			break;		case 'v':			vflag++;			break;		case 'w':			wflag++;			break;		case 'x':			xflag++;			break;		case 't':			tflag++;			break;		case 'm':			mflag++;			break;		case '-':			break;		case '0':		case '1':			magtape[7] = *cp;			usefile = magtape;			break;		case 'b':			nblock = atoi(*argv++);			if (nblock > NBLOCK || nblock <= 0) {				fprintf(stderr, "Invalid blocksize. (Max %d)\n", NBLOCK);				done(1);			}			if (rflag && !cflag)				goto noupdate;			break;		case 'l':			linkerrok++;			break;		default:			fprintf(stderr, "tar: %c: unknown option\n", *cp);			usage();		}	if (rflag) {		if (cflag && tfile != NULL) {			usage();			done(1);		}		if (signal(SIGINT, SIG_IGN) != SIG_IGN)			signal(SIGINT, onintr);		if (signal(SIGHUP, SIG_IGN) != SIG_IGN)			signal(SIGHUP, onhup);		if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)			signal(SIGQUIT, onquit);/*		if (signal(SIGTERM, SIG_IGN) != SIG_IGN)			signal(SIGTERM, onterm);*/		if (strcmp(usefile, "-") == 0) {			if (cflag == 0) {				fprintf(stderr, "Can only create standard output archives\n");				done(1);			}			mt = dup(1);			nblock = 1;		}		else if ((mt = open(usefile, 2)) < 0) {			if (cflag == 0 || (mt =  creat(usefile, 0666)) < 0) {				fprintf(stderr, "tar: cannot open %s\n", usefile);				done(1);			}		}		if (cflag == 0 && nblock == 0)			nblock = 1;		dorep(argv);	}	else if (xflag)  {		if (strcmp(usefile, "-") == 0) {			mt = dup(0);			nblock = 1;		}		else if ((mt = open(usefile, 0)) < 0) {			fprintf(stderr, "tar: cannot open %s\n", usefile);			done(1);		}		doxtract(argv);	}	else if (tflag) {		if (strcmp(usefile, "-") == 0) {			mt = dup(0);			nblock = 1;		}		else if ((mt = open(usefile, 0)) < 0) {			fprintf(stderr, "tar: cannot open %s\n", usefile);			done(1);		}		dotable();	}	else		usage();	done(0);}usage(){	fprintf(stderr, "tar: usage  tar -{txru}[cvfblm] [tapefile] [blocksize] file1 file2...\n");	done(1);}dorep(argv)char	*argv[];{	register char *cp, *cp2;	char wdir[60];	if (!cflag) {		getdir();		do {			passtape();			if (term)				done(0);			getdir();		} while (!endtape());		if (tfile != NULL) {			char buf[200];			strcat(buf, "sort +0 -1 +1nr ");			strcat(buf, tname);			strcat(buf, " -o ");			strcat(buf, tname);			sprintf(buf, "sort +0 -1 +1nr %s -o %s; awk '$1 != prev {print; prev=$1}' %s >%sX;mv %sX %s",				tname, tname, tname, tname, tname, tname);			fflush(tfile);			system(buf);			freopen(tname, "r", tfile);			fstat(fileno(tfile), &stbuf);			high = stbuf.st_size;		}	}	getwdir(wdir);	while (*argv && ! term) {		cp2 = *argv;		for (cp = *argv; *cp; cp++)			if (*cp == '/')				cp2 = cp;		if (cp2 != *argv) {			*cp2 = '\0';			chdir(*argv);			*cp2 = '/';			cp2++;		}		putfile(*argv++, cp2);		chdir(wdir);	}	putempty();	putempty();	flushtape();	if (linkerrok == 1)		for (; ihead != NULL; ihead = ihead->nextp)			if (ihead->count != 0)				fprintf(stderr, "Missing links to %s\n", ihead->pathname);}endtape(){	if (dblock.dbuf.name[0] == '\0') {		backtape();		return(1);	}	else		return(0);}getdir(){	register struct stat *sp;	int i;	readtape( (char *) &dblock);	if (dblock.dbuf.name[0] == '\0')		return;	sp = &stbuf;	sscanf(dblock.dbuf.mode, "%o", &i);	sp->st_mode = i;	sscanf(dblock.dbuf.uid, "%o", &i);	sp->st_uid = i;	sscanf(dblock.dbuf.gid, "%o", &i);	sp->st_gid = i;	sscanf(dblock.dbuf.size, "%lo", &sp->st_size);	sscanf(dblock.dbuf.mtime, "%lo", &sp->st_mtime);	sscanf(dblock.dbuf.chksum, "%o", &chksum);	if (chksum != checksum()) {		fprintf(stderr, "directory checksum error\n");		done(2);	}	if (tfile != NULL)		fprintf(tfile, "%s %s\n", dblock.dbuf.name, dblock.dbuf.mtime);}passtape(){	long blocks;	char buf[TBLOCK];	if (dblock.dbuf.linkflag == '1')		return;	blocks = stbuf.st_size;	blocks += TBLOCK-1;	blocks /= TBLOCK;	while (blocks-- > 0)		readtape(buf);}putfile(longname, shortname)char *longname;char *shortname;{	int infile;	long blocks;	char buf[TBLOCK];	register char *cp, *cp2;	struct direct dbuf;	int i, j;	infile = open(shortname, 0);	if (infile < 0) {		fprintf(stderr, "tar: %s: cannot open file\n", longname);		return;	}	fstat(infile, &stbuf);	if (tfile != NULL && checkupdate(longname) == 0) {		close(infile);		return;	}	if (checkw('r', longname) == 0) {		close(infile);		return;	}	if ((stbuf.st_mode & S_IFMT) == S_IFDIR) {		for (i = 0, cp = buf; *cp++ = longname[i++];);		*--cp = '/';		cp++;		i = 0;		chdir(shortname);		while (read(infile, (char *)&dbuf, sizeof(dbuf)) > 0 && !term) {			if (dbuf.d_ino == 0) {				i++;				continue;			}			if (strcmp(".", dbuf.d_name) == 0 || strcmp("..", dbuf.d_name) == 0) {				i++;				continue;			}			cp2 = cp;			for (j=0; j < DIRSIZ; j++)				*cp2++ = dbuf.d_name[j];			*cp2 = '\0';			close(infile);			putfile(buf, cp);			infile = open(".", 0);			i++;			lseek(infile, (long) (sizeof(dbuf) * i), 0);		}		close(infile);		chdir("..");		return;	}	if ((stbuf.st_mode & S_IFMT) != S_IFREG) {		fprintf(stderr, "tar: %s is not a file. Not dumped\n", longname);		return;	}	tomodes(&stbuf);	cp2 = longname;	for (cp = dblock.dbuf.name, i=0; (*cp++ = *cp2++) && i < NAMSIZ; i++);	if (i >= NAMSIZ) {		fprintf(stderr, "%s: file name too long\n", longname);		close(infile);		return;	}	if (stbuf.st_nlink > 1) {		struct linkbuf *lp;		int found = 0;		for (lp = ihead; lp != NULL; lp = lp->nextp) {			if (lp->inum == stbuf.st_ino && lp->devnum == stbuf.st_dev) {				found++;				break;			}		}		if (found) {			strcpy(dblock.dbuf.linkname, lp->pathname);			dblock.dbuf.linkflag = '1';			sprintf(dblock.dbuf.chksum, "%6o", checksum());			writetape( (char *) &dblock);			if (vflag) {				fprintf(stderr, "a %s ", longname);				fprintf(stderr, "link to %s\n", lp->pathname);			}			lp->count--;			close(infile);			return;		}		else {			lp = (struct linkbuf *) malloc(sizeof(*lp));			if (lp == NULL) {				if (freemem) {					fprintf(stderr, "Out of memory. Link information lost\n");					freemem = 0;				}			}			else {				lp->nextp = ihead;				ihead = lp;				lp->inum = stbuf.st_ino;				lp->devnum = stbuf.st_dev;				lp->count = stbuf.st_nlink - 1;				strcpy(lp->pathname, longname);			}		}	}	blocks = (stbuf.st_size + (TBLOCK-1)) / TBLOCK;	if (vflag) {		fprintf(stderr, "a %s ", longname);		fprintf(stderr, "%ld blocks\n", blocks);	}	sprintf(dblock.dbuf.chksum, "%6o", checksum());	writetape( (char *) &dblock);	while ((i = read(infile, buf, TBLOCK)) > 0 && blocks > 0) {		writetape(buf);		blocks--;	}	close(infile);	if (blocks != 0 || i != 0)		fprintf(stderr, "%s: file changed size\n", longname);	while (blocks-- >  0)		putempty();}doxtract(argv)char	*argv[];{	long blocks, bytes;	char buf[TBLOCK];	char **cp;	int ofile;	for (;;) {		getdir();		if (endtape())			break;		if (*argv == 0)			goto gotit;		for (cp = argv; *cp; cp++)			if (prefix(*cp, dblock.dbuf.name))				goto gotit;		passtape();		continue;gotit:		if (checkw('x', dblock.dbuf.name) == 0) {			passtape();			continue;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -