Auwvax.302 net.sources utcsrgv!utzoo!decvax!harpo!uwvax!solomon Sun Apr 4 09:11:21 1982 Enhancement to tar 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 #include #include --- 1,4 ----- ! static char *sccsid = "@(#)tar.c 4.5.1 (Berkeley) 82/04/04"; #include #include #include *************** *** 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) ----------------------------------------------------------------- gopher://quux.org/ conversion by John Goerzen of http://communication.ucsd.edu/A-News/ This Usenet Oldnews Archive article may be copied and distributed freely, provided: 1. There is no money collected for the text(s) of the articles. 2. The following notice remains appended to each copy: The Usenet Oldnews Archive: Compilation Copyright (C) 1981, 1996 Bruce Jones, Henry Spencer, David Wiseman.