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

📄 diffarch.c

📁 unix 下tar 执行程序的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		if ((filestat.st_mode & S_IFMT) != S_IFREG) {
			fprintf(msg_file, "%s: not a regular file\n",
				head->header.name);
			skip_file((long)hstat.st_size);
			different++;
			break;
		}

		filestat.st_mode &= ~S_IFMT;
		offset = from_oct(1+12, head->header.offset);
		if (filestat.st_size != hstat.st_size + offset) {
			sigh("size");
			skip_file((long)hstat.st_size);
			different++;
			break;
		}

#ifndef __MSDOS__
		diff_fd = open(head->header.name, O_NDELAY|O_RDONLY);
#else
                diff_fd = open(head->header.name, O_NDELAY|O_RDONLY|O_BINARY);
#endif

		if (diff_fd < 0) {
			msg_perror("cannot open file %s",head->header.name);
			skip_file((long)hstat.st_size);
			different++;
			break;
		}
		err = lseek(diff_fd, offset, 0);
		if(err!=offset) {
			msg_perror("cannot seek to %ld in file %s",offset,head->header.name);
			different++;
			break;
		}

		wantbytes((long)(hstat.st_size),compare_chunk);

		check = close(diff_fd);
		if (check < 0) {
			msg_perror("Error while closing %s",head->header.name);
		}
		break;

	}

	/* We don't need to save it any longer. */
	saverec((union record **) 0);	/* Unsave it */
}

int
compare_chunk(bytes,buffer)
long bytes;
char *buffer;
{
	int err;

        err=read(diff_fd,diff_buf,( unsigned ) bytes);
        if(err!=( int ) bytes) {
		if(err<0) {
			msg_perror("can't read %s",head->header.name);
		} else {
                        fprintf(msg_file,"%s: could only read %d of %ld bytes\n",head->header.name,err,bytes);
		}
		different++;
		return -1;
	}
        if(bcmp(buffer,diff_buf,( unsigned ) bytes)) {
		fprintf(msg_file, "%s: data differs\n",head->header.name);
		different++;
		return -1;
	}
	return 0;
}

int
compare_dir(bytes,buffer)
long bytes;
char *buffer;
{
        if(bcmp(buffer,diff_dir,( unsigned ) bytes)) {
		fprintf(msg_file, "%s: data differs\n",head->header.name);
		different++;
		return -1;
	}
	diff_dir+=bytes;
	return 0;
}

/*
 * Sigh about something that differs.
 */
sigh(what)
	char *what;
{

	fprintf(msg_file, "%s: %s differs\n",
		head->header.name, what);
}

verify_volume()
{
	int status;
#ifdef MTIOCTOP
	struct mtop t;
	int er;
#endif

	if(!diff_buf)
		diff_init();
#ifdef MTIOCTOP
	t.mt_op = MTBSF;
	t.mt_count = 1;
	if((er=rmtioctl(archive,MTIOCTOP,&t))<0) {
		if(errno!=EIO || (er=rmtioctl(archive,MTIOCTOP,&t))<0) {
#endif
			if(rmtlseek(archive,0L,0)!=0) {
				/* Lseek failed.  Try a different method */
				msg_perror("Couldn't rewind archive file for verify");
				return;
			}
#ifdef MTIOCTOP
		}
	}
#endif
	ar_reading=1;
	now_verifying = 1;
	fl_read();
	for(;;) {
		status = read_header();
		if(status==0) {
			unsigned n;

			n=0;
			do {
				n++;
				status=read_header();
			} while(status==0);
			msg("VERIFY FAILURE: %d invalid header%s detected!",n,n==1?"":"s");
		}
		if(status==2 || status==EOF)
			break;
		diff_archive();
	}
	ar_reading=0;
	now_verifying = 0;

}

int do_stat(statp)
struct stat *statp;
{
	int err;

	err = f_follow_links ? stat(head->header.name, statp) : lstat(head->header.name, statp);
	if (err < 0) {
		if (errno==ENOENT) {
			fprintf(msg_file, "%s: does not exist\n",head->header.name);
		} else
			msg_perror("can't stat file %s",head->header.name);
/*		skip_file((long)hstat.st_size);
		different++;*/
		return 1;
	} else
		return 0;
}

/*
 * JK
 * Diff'ing a sparse file with its counterpart on the tar file is a 
 * bit of a different story than a normal file.  First, we must know
 * what areas of the file to skip through, i.e., we need to contruct
 * a sparsearray, which will hold all the information we need.  We must
 * compare small amounts of data at a time as we find it.  
 */

diff_sparse_files(filesize)
int	filesize;

{
	int		sparse_ind = 0;
	char		*buf;
	int		buf_size = RECORDSIZE;
	union record 	*datarec;	
	int		err;
	long		numbytes;
	int		amt_read = 0;
	int		size = filesize;

	buf = (char *) malloc(buf_size * sizeof (char));
	
	fill_in_sparse_array();
	

	while (size > 0) {
		datarec = findrec();
		if (!sparsearray[sparse_ind].numbytes)
			break;

		/*
		 * 'numbytes' is nicer to write than
		 * 'sparsearray[sparse_ind].numbytes' all the time ...
		 */
		numbytes = sparsearray[sparse_ind].numbytes;
		
		lseek(diff_fd, sparsearray[sparse_ind].offset, 0);
		/*
		 * take care to not run out of room in our buffer
		 */
		while (buf_size < numbytes) {
			buf = (char *) realloc(buf, buf_size * 2 * sizeof(char));
			buf_size *= 2;
		}
		while (numbytes > RECORDSIZE) {
			if ((err = read(diff_fd, buf, RECORDSIZE)) != RECORDSIZE) {
	 			if (err < 0) 
					msg_perror("can't read %s", head->header.name);
				else
                                        fprintf(msg_file, "%s: could only read %d of %ld bytes\n",
						err, numbytes);
				break;
			}
			if (bcmp(buf, datarec->charptr, RECORDSIZE)) {
				different++;
				break;
			}
			numbytes -= err;
			size -= err;
			userec(datarec);
			datarec = findrec();
		}
                if ((err = read(diff_fd, buf, ( unsigned ) numbytes)) != (int) numbytes) {
 			if (err < 0) 
				msg_perror("can't read %s", head->header.name);
			else
                                fprintf(msg_file, "%s: could only read %d of %ld bytes\n",
						err, numbytes);
			break;
		}

                if (bcmp(buf, datarec->charptr, ( unsigned ) numbytes)) {
			different++;
			break;
		}
/*		amt_read += numbytes;
		if (amt_read >= RECORDSIZE) {
			amt_read = 0;
			userec(datarec);
			datarec = findrec();
		}*/
		userec(datarec);
		sparse_ind++;
		size -= numbytes;
	}
	/* 
	 * if the number of bytes read isn't the
	 * number of bytes supposedly in the file,
	 * they're different
	 */
/*	if (amt_read != filesize)
		different++;*/
	userec(datarec);
	free(sparsearray);
	if (different)
		fprintf(msg_file, "%s: data differs\n", head->header.name);

}

/*
 * JK
 * This routine should be used more often than it is ... look into
 * that.  Anyhow, what it does is translate the sparse information
 * on the header, and in any subsequent extended headers, into an
 * array of structures with true numbers, as opposed to character
 * strings.  It simply makes our life much easier, doing so many
 * comparisong and such.
 */
fill_in_sparse_array()
{
	int 	ind;

	/*
	 * allocate space for our scratch space; it's initially
	 * 10 elements long, but can change in this routine if
	 * necessary
	 */
	sp_array_size = 10;
	sparsearray = (struct sp_array *) malloc(sp_array_size * sizeof(struct sp_array));

	/*
	 * there are at most five of these structures in the header
	 * itself; read these in first
	 */
	for (ind = 0; ind < SPARSE_IN_HDR; ind++) {
		if (!head->header.sp[ind].numbytes)
			break;
		sparsearray[ind].offset =
			from_oct(1+12, head->header.sp[ind].offset);
		sparsearray[ind].numbytes =
			from_oct(1+12, head->header.sp[ind].numbytes);
	}
	/*
	 * if the header's extended, we gotta read in exhdr's till
	 * we're done
	 */
	if (head->header.isextended) {
 	    /* how far into the sparsearray we are 'so far' */
	    static int so_far_ind = SPARSE_IN_HDR;	
	    union record *exhdr;
   	    
	    for (;;) {
		exhdr = findrec();
		for (ind = 0; ind < SPARSE_EXT_HDR; ind++) {
			if (ind+so_far_ind > sp_array_size-1) {
				/*
 				 * we just ran out of room in our
				 *  scratch area - realloc it
 				 */
				sparsearray = (struct sp_array *)
					realloc(sparsearray, 
						sp_array_size*2*sizeof(struct sp_array));
				sp_array_size *= 2;
			}
			/*
			 * convert the character strings into longs
			 */
			sparsearray[ind+so_far_ind].offset = 
			    from_oct(1+12, exhdr->ext_hdr.sp[ind].offset);
			sparsearray[ind+so_far_ind].numbytes =
			    from_oct(1+12, exhdr->ext_hdr.sp[ind].numbytes);
		}
		/* 
		 * if this is the last extended header for this
		 * file, we can stop
		 */
		if (!exhdr->ext_hdr.isextended)
			break;
		else {
			so_far_ind += SPARSE_EXT_HDR;
			userec(exhdr);
		}
	    }
	    /* be sure to skip past the last one  */
	    userec(exhdr);
	}
}

⌨️ 快捷键说明

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