nvt9001@belvoir-emh3.army.mil (DoN Nichols) (06/20/89)
> From: lad <lad@lad.uucp> > Subject: Tar Problem -- HELP!!! > I hope one of you wizards can help. I'm not really a wizard, but I believe that I know something which can help you here. [summary: I created an archive, remade the file system, and overwrote the head of the archive instead of restoring from it - DoN. ] > The question: Is there any way to recover those files from that tape? The > second tar command should only have initialized the first few blocks of the tape. I know my files are on the rest of it. > > If someone knows what to do, please call me at the number below. I will pay > your LD charges! Anything anyone can do to help will be appreciated. > The process of turning the wizards newsgroup into a digest seems to have stripped off your phone number, etc, and I can't get the local mailer to accept uucp addresses with any reliability, so I'm posting to the net. The GNU tar program has an option (-i ignore blocks of zeros in the archive) which is said to be useful for reading multiple archives cat'ed together, or damaged archives. You definately have the latter, and It will look somewhat like the former, so this may help. I'm assuming that you have enought of your system left to be able to compile and link a program. I can't do it for you on my system, since you specified a blocking factor of 100, and my tape interface hardware chokes above a blocking factor of 40. The tar itself will work with any blocking factor that your system hardware will accept. If you have ftp access to simtel20.army.mil or another comp.sources.unix archive site, you can get it directly. If not, give me an evening call (703) 938-4564, (Usually after 6:15PM EST/EDT), and we'll try sending you a tar file of the sources) Sorry that this isn't a quick fix, but it it least offers some hope. Good Luck DoN. (Donald Nichols) <nvt9001@belvoir-emh3.army.mil> Disclaimers: 1) My employer doesn't pay me enough to speak for him. 2) The system from which I offer help is not this one with net access, but my personal one at home.
fmr@cwi.nl (Frank Rahmani) (06/21/89)
>> Subject: Tar Problem -- HELP!!! >> I hope one of you wizards can help. You don't nmeed any wizard to do this, its just routine work done daily by the operators on every big UNIX(tm) site. > I'm not really a wizard, but I believe that I know something which can > help you here. edited a whole complicated procedure description > > Sorry that this isn't a quick fix, but it it least offers some hope. Neither is mine, but as there are only some 5 files involved this will be acceptable. The amount of recovery time is proportional to the number of files to recover. > 1) My employer doesn't pay me enough to speak for him. Neither does mine, I'm just trying to help. I include the original posting as I received it. The description on the manpage is clear. Should compile under any flavor of UNIX(tm). It is in daily use at our site and has rescued many otherwise unreadable files. -------------------------- Relay-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site mcvax.mcvax.UUCP Path: mcvax!seismo!uwvax!husc6!wjh12!mirror!sources-request From: sources-request@mirror.UUCP Newsgroups: mod.sources Subject: v07i002: Tools to read damaged tar tapes (tar_aids) Message-ID: <205@mirror.UUCP> Date: 25 Aug 86 20:35:49 GMT Article-I.D.: mirror.205 Posted: Mon Aug 25 22:35:49 1986 Date-Received: 26 Aug 86 22:56:42 GMT Sender: rs@mirror.UUCP Organization: Mirror Systems, Cambridge MA Lines: 393 Approved: rs@mirror.UUCP Submitted by: pyramid!utzoo!henry Mod.sources: Volume 7, Issue 2 Archive-name: tar_aids [ I wrote the Makefile and repacked the archive. These tools are very useful! --r$ ] #!/bin/sh # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # Exit status; set to 1 on "wc" errors or if would overwrite. STATUS=0 # Contents: README Makefile targ.1 targ.c tarl.c echo x - README if test -f README ; then echo README exists, putting output in $$README OUT=$$README STATUS=1 else OUT=README fi sed 's/^XX//' > $OUT <<'@//E*O*F README//' XXHere are two small public-domain programs for scavenging files from XXdamaged tar tapes. They don't sing or dance, but they are highly XXportable, and they are simple enough that they are readily understood XXand changed to meet special requirements. They aren't the most XXbeautiful code on Earth, since they are basically cleaned-up versions XXof quick-and-dirty improvisations. They do, however, work. @//E*O*F README// chmod u=rw,g=rw,o=rw $OUT echo x - Makefile if test -f Makefile ; then echo Makefile exists, putting output in $$Makefile OUT=$$Makefile STATUS=1 else OUT=Makefile fi sed 's/^XX//' > $OUT <<'@//E*O*F Makefile//' XXall: targ tarl XXtarg: targ.c XX cc $(CFLAGS) -o $@ $< XXtarl: tarl.c XX cc $(CFLAGS) -o $@ $< XX# The 'echo' causes the "right thing" to happen on 4.[23]BSD systems. XXDEST = /usr/local/bin XXMAN = /usr/man/man1 XXinstall: all XX cp targ tarl $DEST XX cp targ.1 $MAN/targ.1 XX echo ".so man1/tarl.1" >$MAN/targ.1 @//E*O*F Makefile// chmod u=rw,g=rw,o=rw $OUT echo x - targ.1 if test -f targ.1 ; then echo targ.1 exists, putting output in $$targ.1 OUT=$$targ.1 STATUS=1 else OUT=targ.1 fi sed 's/^XX//' > $OUT <<'@//E*O*F targ.1//' XX.TH TARG 1 local XX.DA 23 July 1986 XX.SH NAME XXtarg, tarl \- recover files from damaged tar-format archives XX.SH SYNOPSIS XX\fBtarg\fR file ... XX.PP XX\fBtarl\fR XX.SH DESCRIPTION XX\fITarg\fR and \fItarl\fR are used to list and recover files from a XXdamaged \fItar\fR(1) archive. XXThey use a simplistic pattern-matching XXapproach to identify \fItar\fR header blocks. XXBoth will cheerfully ignore all sorts of bad things about the archive XX(such as wrong checksums, read errors, and scraped-off magnetic surface...), XXup to a maximum of twenty hard errors in a row. XXThey report on such things as apparent end-of-file. XXBoth programs read the \fItar\fR archive from standard input. XX.PP XX\fITarl\fR lists the file names it sees in the archive. XXIt is particularly useful for XXpreparing a file of names for use with \fItarg\fR. XX.PP XX\fITarg\fR takes file or directory names as arguments XXand attempts to extract them from the archive. XX\fITarg\fR is not willing to create directories, however, XXso these must be made manually beforehand if they do not already exist. XXFiles are owned by the user, and have his default permissions. XX.SH EXAMPLE XX``tarl < /dev/rmt8 > filelist'' lists all files on the tape XXmounted on /dev/rmt8 and places the results in ``filelist''. XX.PP XX``targ joe/precious < /dev/rmt0'' restores the file XX``joe/precious'' from the tape mounted on /dev/rmt0. XXThe directory ``joe'' must already exist. XX.SH SEE ALSO XXtar(1) XX.SH HISTORY XXWritten by Henry Spencer, Univ. of Toronto Zoology. XXThis software is public domain. XXManual page by Chris Robertson. XX.SH BUGS XX\fITarg\fR should be smarter about directories and permissions. XX.PP XXThey really should use the \fItar\fR header-block checksum, XXinstead of the slightly-arcane pattern matcher, to identify header blocks. @//E*O*F targ.1// chmod u=rw,g=rw,o=rw $OUT echo x - targ.c if test -f targ.c ; then echo targ.c exists, putting output in $$targ.c OUT=$$targ.c STATUS=1 else OUT=targ.c fi sed 's/^XX//' > $OUT <<'@//E*O*F targ.c//' XX#include <stdio.h> XX#define NAMSIZ 100 XXstruct matches { XX int offset; XX char value; XX} matches[] = { XX NAMSIZ+6, ' ', XX NAMSIZ+7, '\0', XX NAMSIZ+8+6, ' ', XX NAMSIZ+8+7, '\0', XX NAMSIZ+16+6, ' ', XX NAMSIZ+16+7, '\0', XX NAMSIZ+24+11, ' ', XX NAMSIZ+36+11, ' ', XX NAMSIZ+48+6, '\0', XX 0, 0, XX}; XXint XXistar(block) XXchar *block; XX{ XX int loop; XX for (loop = 0; matches[loop].offset != 0; loop++) XX if (block[matches[loop].offset] != matches[loop].value) XX return(0); XX return(1); XX} XXchar buf[10240]; XXint bad; XXint nleft = 0; XXint whichnow; XXint opened = 0; XXint f; XXlong nwrite; XXmain(argc, argv) XXint argc; XXchar **argv; XX{ XX int loop; XX char *block; XX extern char *readblock(); XX bad = 0; XX for(;;) { XX block = readblock(0); XX if (block != NULL) XX doblock(block, argc, argv); XX } XX} XXdoblock(block, argc, argv) XXchar *block; XXint argc; XXchar **argv; XX{ XX int count; XX if (istar(block)) { XX if (opened) { XX printf("--- premature end\n"); XX close(f); XX opened = 0; XX } XX if (match(block, argc, argv)) { XX f = creat(block, 0666); XX if (f < 0) XX printf("--- unable to create %s\n", block); XX else { XX opened = 1; XX sscanf(block+NAMSIZ+24, "%lo", &nwrite); XX printf("--- reading %s %ld\n", block, nwrite); XX if (nwrite <= 0) { XX close(f); XX opened = 0; XX printf("--- done\n"); XX } XX } XX } XX } else { XX if (opened) { XX count = (nwrite > 512) ? 512 : (int)nwrite; XX write(f, block, count); XX nwrite -= count; XX if (nwrite <= 0) { XX opened = 0; XX close(f); XX printf("--- done\n"); XX } XX } XX } XX} XXint XXmatch(s, argc, argv) XXchar *s; XXint argc; XXchar **argv; XX{ XX int i; XX int c; XX for (i = 1; i < argc; i++) { XX if (strncmp(s, argv[i], strlen(argv[i])) == 0) { XX c = s[strlen(argv[i])]; XX if (c == '\0' || c == '/') XX return(1); XX } XX } XX return(0); XX} XXchar * XXreadblock(desc) XXint desc; XX{ XX int count; XX if (nleft > 0) { XX whichnow++; XX nleft--; XX return(buf+whichnow*512); XX } XX count = read(desc, buf, (int)sizeof(buf)); XX if (count <= 0 || count%512 != 0) { XX if (count == 0) XX printf("---apparent EOF\n"); XX else XX printf("---error\n"); XX if (bad > 20) XX exit(1); XX bad++; XX return(NULL); XX } XX bad = 0; XX whichnow = 0; XX nleft = count/512 - 1; XX return(buf); XX} @//E*O*F targ.c// chmod u=rw,g=rw,o=rw $OUT echo x - tarl.c if test -f tarl.c ; then echo tarl.c exists, putting output in $$tarl.c OUT=$$tarl.c STATUS=1 else OUT=tarl.c fi sed 's/^XX//' > $OUT <<'@//E*O*F tarl.c//' XX#include <stdio.h> XX#define NAMSIZ 100 XXstruct matches { XX int offset; XX char value; XX} matches[] = { XX NAMSIZ+6, ' ', XX NAMSIZ+7, '\0', XX NAMSIZ+8+6, ' ', XX NAMSIZ+8+7, '\0', XX NAMSIZ+16+6, ' ', XX NAMSIZ+16+7, '\0', XX NAMSIZ+24+11, ' ', XX NAMSIZ+36+11, ' ', XX NAMSIZ+48+6, '\0', XX 0, 0, XX}; XXint XXistar(block) XXchar *block; XX{ XX int loop; XX for (loop = 0; matches[loop].offset != 0; loop++) XX if (block[matches[loop].offset] != matches[loop].value) XX return(0); XX return(1); XX} XXchar buf[10240]; XXint bad; XXint nleft = 0; XXint whichnow; XXmain() XX{ XX int loop; XX int dir; XX char *block; XX extern char *readblock(); XX bad = 0; XX for(;;) { XX block = readblock(0); XX if (block != NULL && istar(block)) XX printf("%s\n", block); XX } XX} XXchar * XXreadblock(desc) XXint desc; XX{ XX int count; XX if (nleft > 0) { XX whichnow++; XX nleft--; XX return(buf+whichnow*512); XX } XX count = read(desc, buf, (int)sizeof(buf)); XX if (count <= 0 || count%512 != 0) { XX if (count == 0) XX printf("---apparent EOF\n"); XX else XX printf("---error\n"); XX if (bad > 20) XX exit(1); XX bad++; XX return(NULL); XX } XX bad = 0; XX whichnow = 0; XX nleft = count/512 - 1; XX return(buf); XX} @//E*O*F tarl.c// chmod u=rw,g=rw,o=rw $OUT echo Inspecting for damage in transit... temp=/tmp/sharin$$; dtemp=/tmp/sharout$$ trap "rm -f $temp $dtemp; exit" 0 1 2 3 15 cat > $temp <<\!!! 6 60 398 README 15 48 295 Makefile 46 274 1744 targ.1 147 329 2148 targ.c 81 163 1112 tarl.c 295 874 5697 total !!! wc $FILES | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp if test -s $dtemp ; then echo "Ouch [diff of wc output]:" cat $dtemp STATUS=1 elif test $STATUS = 0 ; then echo "No problems found." else echo "WARNING -- PROBLEMS WERE FOUND..." fi exit $STATUS -------------------------- end of forwarded file. If you have any questions left feel free to contact me. fmr@cwi.nl -- It is better never to have been born. But who among us has such luck? Maintainer's Motto: If we can't fix it, it ain't broke. These opinions are solely mine and in no way reflect those of my employer.
samperi@marob.masa.com (Dominick Samperi) (06/24/89)
In article <926@sering.cwi.nl> fmr@cwi.nl (Frank Rahmani) writes: >I include the original posting as I received it. The description on the >manpage is clear. Should compile under any flavor of UNIX(tm). It is >in daily use at our site and has rescued many otherwise unreadable files. ^^^^^ I don't think this really solves the original problem, which results from a rather unreliable tape backup standard (QIC-24). Sure, the posted utility can be used to recover files from a damaged tar archive, but this problem occurs at the user buffer level, and the problem is that these cartridge devices will not skip over a small segment that was written in error in order to find data that was in the first segment originally. After overwriting a large tape segment, the only low-level command that one can use is "find next file mark", and this is not very helpful. -- Dominick Samperi -- ESCC samperi@marob.masa.com uunet!hombre!samperi
lad@lad.UUCP (lad) (07/23/89)
I hope one of you wizards can help. I careated a tar archive of a directory on a 1/2" tape drive on a Sun 3/180. I used the command : % tar cvbf 100 /dev/rmt8 /usr13 to create the archive. I newfs'ed the fs and went to restore the fs again. I cd'd to /usr13 and then typed: % tar cvbf 100 /dev/rmt8 again. Before I could stop myself I hit RETURN and then I realized what I did. The question: Is there any way to recover those files from that tape? The second tar command should only have initialized the first few blocks of the tape. I know my files are on the rest of it. If someone knows what to do, please call me at the number below. I will pay your LD charges! Anything anyone can do to help will be appreciated.