How to Save a 120G tar file, well most of it

Submitted by colonel on Fri, 10/09/2009 - 16:51

We could extract a small part of the file with 'tar xvf file.tar' but we would get a 'tar: Skipping to next header' before it would reach the directory we wanted.

Off to: http://aplawrence.com/Bofcusm/2646.html
and get the find_tar_headers.pl script, because of the number of files in our tar file we saved the output from find_tar_headers.pl into a text file so we could search it later. Found the starting point of the directory we are looking for, and use bc

bc 1.06.94
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
scale=4
43618577409/1024
42596267.0009

Run the dd command

dd if=file.tar of=file-tail.tar bs=1k skip=42596267

Tar still didn't work because the file was not recognized as a tar file

file file.tar
file.tar: data

Next is cpio

cpio -ivd -H tar < file-tail.tar

And we got our directory back

The cpio advice was found here:
http://www.linuxquestions.org/questions/linux-software-2/recovering-file...

Here is the perl script from http://aplawrence.com/Bofcusm/2646.html

#!/usr/bin/perl -w
use strict;

# 99.9% of all credits for this script go
# to Tore Skjellnes
# who is the originator.

my $tarfile;
my $c;
my $hit;
my $header;

# if you don't get any results, outcomment the line below and
# decomment the line below the it and retry
my @src = (ord('u'),ord('s'),ord('t'),ord('a'),ord('r'),ord(" "), ord(" "),0);
#my @src = (ord('u'),ord('s'),ord('t'),ord('a'),ord('r'),0,ord('0'),ord('0'));

die "No tar file given on command line" if $#ARGV != 0;

$tarfile = $ARGV[0];

open(IN,$tarfile) or die "Could not open `$tarfile': $!";

$hit = 0;
$| = 1;
seek(IN,257,0) or die "Could not seek forward 257 characters in `$tarfile': $!";
while (read(IN,$c,1) == 1)
{
($hit = 0, next) unless (ord($c) == $src[$hit]);
$hit = $hit + 1;
( print "hit: $hit", next ) unless $hit > $#src;

# we have a probable header at (pos - 265)!
my $pos = tell(IN) - 265;
seek(IN,$pos,0)
or (warn "Could not seek to position $pos in `$tarfile': $!", next);

(read(IN,$header,512) == 512)
or (warn "Could not read 512 byte header at position $pos in `$tarfile': $!", seek(IN,$pos+265,0),next
);

my ($name, $mode, $uid, $gid, $size, $mtime, $chksum, $typeflag,
$linkname, $magic, $version, $uname, $gname,
$devmajor, $devminor, $prefix)
= unpack ("Z100a8a8a8Z12a12a8a1a100a6a2a32a32a8a8Z155", $header);
$size = int $size;
printf("%s:%s:%s:%s\n",$tarfile,$pos,$name,$size);

$hit = 0;
}

close(IN) or warn "Error closing `$tarfile': $!";