📄 diffarch.c
字号:
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 + -