Recovering corrupted tar's
Jean-Pierre Radley
jpr at jpradley.uucp
Sun Oct 14 06:15:53 AEST 1990
In article <ENAG.90Oct4231246 at svarte.ifi.uio.no> enag at ifi.uio.no (Erik Naggum) writes:
>In article <4121 at neuro.med.umn.edu> alk at neuro.med.umn.edu (Anthony L Kimball) writes:
>
> So, anyone have a handy-dandy tool to patch a tar archive which
> has had it's leading N blocks overwritten? I do so hate to do this
> by hand.
>
>The files occupying the first n blocks are lost, where n >= N. The
>problem is to find the value of n.
> ......
> Searching programs shouldn't be that
>hard to write, either, but I don't think anybody has done this, yet.
Well, this often helps:
/* tarskip.c
* taken from volume 2, number 8 of Unix World.
* Usage: tarskip pathname [tardevice] | tar xvfn -
* The pathname argument is the first file you can
* think of after the bad spot on the archive.
*/
#include <stdio.h>
#define TARBLKSZ 1024 /* Block size on YOUR tar disk */
#define TRUE 1 /* Boolean true */
#define FALSE 0 /* Boolean false */
/* Global variables */
FILE *fp, *efopen(); /* file pointer for tar device file */
char fd; /* file descriptor for tar device file */
char buf[TARBLKSZ]; /* buffer for "tar blocks" */
char *progname;
char *tardev = "/dev/rfd0"; /* Substitute YOUR default device name !! */
main(argc, argv)
int argc;
char *argv[];
{
char *pathname;
int match = FALSE; /*Initialize to zero */
progname = argv[0];
/* Process command line arguments */
if (argc == 1 || argc > 3) { /* Correct # of args? */
error("Usage: %s pathname [tardevice] | tar xvfn -", progname); }
pathname = argv[1]; /* The pattern string to search for */
if (argc == 3)
tardev= argv[2]; /* Use device other than default */
fp= efopen(tardev,"r"); /* Open for reading */
fd= fileno(fp); /* File descriptor */
/* Find block containing desired pathname */
do { getblk(tardev);
match = strncmp(pathname, buf, strlen(pathname));
} while (match);
/* Then read and process disk blocks "forever" */
while (TRUE) { write(1, buf, sizeof(buf));
getblk(tardev); }
}
getblk(device) /* Read the next block into the buffer */
char *device; /* The tar disk device name */
{
int c, done, n;
begin: n = (read(fd, buf, sizeof(buf))); /* Read a block */
if (n ==0) { /* End of disk */
done = query("\nEnd of disk, read another (y/n)? ");
if (!done) { /* Not done */
close(fd); /* Close previous device */
fprintf(stderr, "Insert next disk and");
fprintf(stderr, " press <ENTER> when ready\n");
while ((c=getchar()) != '\n' && c != EOF)
; /* Wait for ENTER */
fp= efopen(device,"r"); /* Open for reading */
fd= fileno(fp); /* File descriptor */
goto begin; /* Get first block from next disk */
} else /* Done */
exit (0);
} else if (n < 0) { /* Tape read error */
done = query("\nRead error, ignore (y/n)? ");
if (done) {
close(fd);
fprintf(stderr, "Goodbye ... \n");
exit(2);
}
}
}
query(msg) /* Display message and prompt for continuance */
char *msg;
{
int c, c2;
fprintf(stderr, "%s", msg);
c = c2 = getchar();
while (c2 != '\n' && c2 != EOF)
c2 = getchar(); /* Ignore remaining input */
if (c == 'y' || c == 'Y') /* First char was y or Y */
return(0); /* Not done */
else
return(1); /* Done */
}
error(s1, s2) /* print error message and die */
char *s1, *s2;
{
extern int errno, sys_nerr;
extern char *sys_errlist[], *progname;
if (progname)
fprintf(stderr, "%s: ", progname);
fprintf(stderr, s1, s2);
if (errno >0 && errno < sys_nerr)
fprintf(stderr, " (%s)", sys_errlist[errno]);
fprintf(stderr, "\n");
exit(1);
}
FILE *efopen(file, mode) /* fopen file, call error() & die if can't */
char *file, *mode;
{
FILE *f;
extern char *progname;
char str[80], *s=str;
if ((f = fopen(file,mode)) != (FILE *)0)
return f;
sprintf(s, "can't open file %s mode %s\n", file, mode);
error(s);
}
--
Jean-Pierre Radley HIGH-Q jpr at jpradley CIS: 72160,1341
More information about the Comp.unix.misc
mailing list