Use a more robust scheme for determining how many blocks to skip
after an EOT-terminated volume. We keep track of the current record number, and synchronise it with the c_tapea field each time we read a header. Avoid the use of c_firstrec because some bugs in dump can cause it to be set incorrectly. Move the initialisation of some variables to avoid compiler warnings.
This commit is contained in:
parent
939bc65715
commit
ab3d6ee098
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=90827
@ -74,7 +74,7 @@ static int numtrec;
|
|||||||
static char *tapebuf;
|
static char *tapebuf;
|
||||||
static union u_spcl endoftapemark;
|
static union u_spcl endoftapemark;
|
||||||
static long blksread; /* blocks read since last header */
|
static long blksread; /* blocks read since last header */
|
||||||
static long tpblksread = 0; /* TP_BSIZE blocks read */
|
static long tapeaddr = 0; /* current TP_BSIZE tape record */
|
||||||
static long tapesread;
|
static long tapesread;
|
||||||
static jmp_buf restart;
|
static jmp_buf restart;
|
||||||
static int gettingfile = 0; /* restart has a valid frame */
|
static int gettingfile = 0; /* restart has a valid frame */
|
||||||
@ -211,7 +211,6 @@ setup()
|
|||||||
if (gethead(&spcl) == FAIL) {
|
if (gethead(&spcl) == FAIL) {
|
||||||
blkcnt--; /* push back this block */
|
blkcnt--; /* push back this block */
|
||||||
blksread--;
|
blksread--;
|
||||||
tpblksread--;
|
|
||||||
cvtflag++;
|
cvtflag++;
|
||||||
if (gethead(&spcl) == FAIL) {
|
if (gethead(&spcl) == FAIL) {
|
||||||
fprintf(stderr, "Tape is not a dump tape\n");
|
fprintf(stderr, "Tape is not a dump tape\n");
|
||||||
@ -300,7 +299,7 @@ void
|
|||||||
getvol(nextvol)
|
getvol(nextvol)
|
||||||
long nextvol;
|
long nextvol;
|
||||||
{
|
{
|
||||||
long newvol, savecnt, savetpcnt, i;
|
long newvol, prevtapea, savecnt, i;
|
||||||
union u_spcl tmpspcl;
|
union u_spcl tmpspcl;
|
||||||
# define tmpbuf tmpspcl.s_spcl
|
# define tmpbuf tmpspcl.s_spcl
|
||||||
char buf[TP_BSIZE];
|
char buf[TP_BSIZE];
|
||||||
@ -309,6 +308,8 @@ getvol(nextvol)
|
|||||||
tapesread = 0;
|
tapesread = 0;
|
||||||
gettingfile = 0;
|
gettingfile = 0;
|
||||||
}
|
}
|
||||||
|
prevtapea = tapeaddr;
|
||||||
|
savecnt = blksread;
|
||||||
if (pipein) {
|
if (pipein) {
|
||||||
if (nextvol != 1) {
|
if (nextvol != 1) {
|
||||||
panic("Changing volumes on pipe input?\n");
|
panic("Changing volumes on pipe input?\n");
|
||||||
@ -320,10 +321,7 @@ getvol(nextvol)
|
|||||||
return;
|
return;
|
||||||
goto gethdr;
|
goto gethdr;
|
||||||
}
|
}
|
||||||
savecnt = blksread;
|
|
||||||
savetpcnt = tpblksread;
|
|
||||||
again:
|
again:
|
||||||
tpblksread = savetpcnt;
|
|
||||||
if (pipein)
|
if (pipein)
|
||||||
done(1); /* pipes do not get a second chance */
|
done(1); /* pipes do not get a second chance */
|
||||||
if (command == 'R' || command == 'r' || curfile.action != SKIP)
|
if (command == 'R' || command == 'r' || curfile.action != SKIP)
|
||||||
@ -425,11 +423,10 @@ getvol(nextvol)
|
|||||||
* If coming to this volume at random, skip to the beginning
|
* If coming to this volume at random, skip to the beginning
|
||||||
* of the next record.
|
* of the next record.
|
||||||
*/
|
*/
|
||||||
dprintf(stdout, "read %ld recs, tape starts with %ld\n",
|
dprintf(stdout, "last rec %ld, tape starts with %ld\n", prevtapea,
|
||||||
tpblksread, tmpbuf.c_firstrec);
|
tmpbuf.c_tapea);
|
||||||
if (tmpbuf.c_type == TS_TAPE && (tmpbuf.c_flags & DR_NEWHEADER)) {
|
if (tmpbuf.c_type == TS_TAPE && (tmpbuf.c_flags & DR_NEWHEADER)) {
|
||||||
if (curfile.action != USING) {
|
if (curfile.action != USING) {
|
||||||
tpblksread = tmpbuf.c_firstrec;
|
|
||||||
/*
|
/*
|
||||||
* XXX Dump incorrectly sets c_count to 1 in the
|
* XXX Dump incorrectly sets c_count to 1 in the
|
||||||
* volume header of the first tape, so ignore
|
* volume header of the first tape, so ignore
|
||||||
@ -438,12 +435,17 @@ getvol(nextvol)
|
|||||||
if (volno != 1)
|
if (volno != 1)
|
||||||
for (i = tmpbuf.c_count; i > 0; i--)
|
for (i = tmpbuf.c_count; i > 0; i--)
|
||||||
readtape(buf);
|
readtape(buf);
|
||||||
} else if (tmpbuf.c_firstrec > 0 &&
|
} else if (tmpbuf.c_tapea <= prevtapea) {
|
||||||
tmpbuf.c_firstrec < tpblksread - 1) {
|
|
||||||
/*
|
/*
|
||||||
* -1 since we've read the volume header
|
* Normally the value of c_tapea in the volume
|
||||||
|
* header is the record number of the header itself.
|
||||||
|
* However in the volume header following an EOT-
|
||||||
|
* terminated tape, it is the record number of the
|
||||||
|
* first continuation data block (dump bug?).
|
||||||
|
*
|
||||||
|
* The next record we want is `prevtapea + 1'.
|
||||||
*/
|
*/
|
||||||
i = tpblksread - tmpbuf.c_firstrec - 1;
|
i = prevtapea + 1 - tmpbuf.c_tapea;
|
||||||
dprintf(stderr, "Skipping %ld duplicate record%s.\n",
|
dprintf(stderr, "Skipping %ld duplicate record%s.\n",
|
||||||
i, i > 1 ? "s" : "");
|
i, i > 1 ? "s" : "");
|
||||||
while (--i >= 0)
|
while (--i >= 0)
|
||||||
@ -855,7 +857,7 @@ readtape(buf)
|
|||||||
if (blkcnt < numtrec) {
|
if (blkcnt < numtrec) {
|
||||||
memmove(buf, &tapebuf[(blkcnt++ * TP_BSIZE)], (long)TP_BSIZE);
|
memmove(buf, &tapebuf[(blkcnt++ * TP_BSIZE)], (long)TP_BSIZE);
|
||||||
blksread++;
|
blksread++;
|
||||||
tpblksread++;
|
tapeaddr++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (i = 0; i < ntrec; i++)
|
for (i = 0; i < ntrec; i++)
|
||||||
@ -961,7 +963,7 @@ readtape(buf)
|
|||||||
blkcnt = 0;
|
blkcnt = 0;
|
||||||
memmove(buf, &tapebuf[(blkcnt++ * TP_BSIZE)], (long)TP_BSIZE);
|
memmove(buf, &tapebuf[(blkcnt++ * TP_BSIZE)], (long)TP_BSIZE);
|
||||||
blksread++;
|
blksread++;
|
||||||
tpblksread++;
|
tapeaddr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1153,6 +1155,7 @@ gethead(buf)
|
|||||||
buf->c_dinode.di_uid = buf->c_dinode.di_ouid;
|
buf->c_dinode.di_uid = buf->c_dinode.di_ouid;
|
||||||
buf->c_dinode.di_gid = buf->c_dinode.di_ogid;
|
buf->c_dinode.di_gid = buf->c_dinode.di_ogid;
|
||||||
}
|
}
|
||||||
|
tapeaddr = buf->c_tapea;
|
||||||
if (dflag)
|
if (dflag)
|
||||||
accthdr(buf);
|
accthdr(buf);
|
||||||
return(GOOD);
|
return(GOOD);
|
||||||
|
Loading…
Reference in New Issue
Block a user