Enhancement to tar
utzoo!decvax!harpo!uwvax!solomon
utzoo!decvax!harpo!uwvax!solomon
Sun Apr 4 09:11:21 AEST 1982
I think I missed the original query, but a recent response in net.wanted
indicated that somebody else has been stung by tar's ungraceful method
of dealing with tape errors. A six-line change to tar helps a whole lot.
Here's the idea: tar organizes its tape into a series of 512-byte logical
records. Each file is represented by a header record (misleadingly called
a "directory block") followed by some number of data records containing
the bits of the file. The header record contains the length of the file,
so tar can figure out where the next header is. As a robustness feature,
tar adds a software checksum to the header, so that it will not confuse
a data record with a header record. Unfortunately, its response to
encountering a data record when it expects a header is to exit.
Some time ago, someone here accidentally started to overwrite a valuable
tar tape. He killed the job after only a couple of blocks of the first file
had been destroyed, but was having difficulty recovering the rest of the
files. I added a new flag that causes tar to retry after a "directory
checksum error" rather than quitting. The changes were made to an
earlier (4.0BSD) version, so I hacked them into the current version
just to get an uncluttered diff. These changes have not been tested
but should be correct modulo minor typos. If you don't like all those
"directory checksum error" messages, just put the line containing the
"goto" one line earlier.
*** tar.c.old Sun Apr 4 08:43:09 1982
--- tar.c Sun Apr 4 08:50:40 1982
***************
*** 1,4
! static char *sccsid = "@(#)tar.c 4.5 (Berkeley) 81/04/02";
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
--- 1,4 -----
! static char *sccsid = "@(#)tar.c 4.5.1 (Berkeley) 82/04/04";
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
***************
*** 38,43
struct stat stbuf;
int rflag, xflag, vflag, tflag, mt, cflag, mflag, fflag, oflag, pflag;
int term, chksum, wflag, recno, first, linkerrok;
int freemem = 1;
int nblock = NBLOCK;
--- 38,44 -----
struct stat stbuf;
int rflag, xflag, vflag, tflag, mt, cflag, mflag, fflag, oflag, pflag;
+ int skipflag; /* solomon, 4/4/82 */
int term, chksum, wflag, recno, first, linkerrok;
int freemem = 1;
int nblock = NBLOCK;
***************
*** 131,136
case 'l':
linkerrok++;
break;
default:
fprintf(stderr, "tar: %c: unknown option\n", *cp);
usage();
--- 132,140 -----
case 'l':
linkerrok++;
break;
+ case 's': /* solomon 4/4/82 */
+ skipflag++;
+ break;
default:
fprintf(stderr, "tar: %c: unknown option\n", *cp);
usage();
***************
*** 275,280
register struct stat *sp;
int i;
readtape( (char *) &dblock);
if (dblock.dbuf.name[0] == '\0')
return;
--- 279,285 -----
register struct stat *sp;
int i;
+ again: /* solomon, 4/4/82 */
readtape( (char *) &dblock);
if (dblock.dbuf.name[0] == '\0')
return;
***************
*** 290,295
sscanf(dblock.dbuf.chksum, "%o", &chksum);
if (chksum != checksum()) {
fprintf(stderr, "directory checksum error\n");
done(2);
}
if (tfile != NULL)
--- 295,301 -----
sscanf(dblock.dbuf.chksum, "%o", &chksum);
if (chksum != checksum()) {
fprintf(stderr, "directory checksum error\n");
+ if (skipflag) goto again; /* solomon, 4/4/82 */
done(2);
}
if (tfile != NULL)
More information about the Comp.sources.unix
mailing list