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