This module can be used to extract the given backup to the local system.

I use this to nightly extract the latest backup's from the backup pool for clients to easily access the last known state.

--
Best regards,
N. van IJzendoorn

<http://www.engineering-spirit.nl/>       Engineering Spirit
Angstelkade 2a-1.11,
3631 NA Nieuwersluis
The Netherlands
tel: (+31)85-2733461 <skype:+31852733461?call>
www.engineering-spirit.nl <http://www.engineering-spirit.nl/> skype:engineering-spirit.nl <skype:engineering-spirit.nl?call>

#!/opt/bin/perl
#============================================================= -*-perl-*-
#
# BackupPC_extract: create an uncompressed dump of the backup
#
# DESCRIPTION
#
#   Usage: BackupPC_extract [options] files/directories...
#
#   Flags:
#   Required options:
#       -h host         host from which you want to rebuild the directory
#       -n dumpNum      dump number from which the rebuild is created
#                       A negative number means relative to the end (eg -1
#                       means the most recent dump, -2 2nd most recent etc).
#       -s shareName    share name from which the rebuild
#
#    Other options:
#       -t              print summary totals
##       -r pathRemove   path prefix that will be replaced with pathAdd
##       -p pathAdd      new path prefix
#       -e charset      charset for encoding file names (default: cp1252)
#
# AUTHOR
#   Nick van IJzendoorn <dipswi...@ownage4u.nl>
#   Based on Backup_zipCreate by Guillaume Filion <g...@users.sourceforge.net>
#   Based on Backup_tarCreate by Craig Barratt <cbarr...@users.sourceforge.net>
#
# COPYRIGHT
#   Copyright (C) 2002-2009  Craig Barratt and Guillaume Filion
#     and Nick van IJzendoorn
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, o
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
#========================================================================
#
#
# See http://backuppc.sourceforge.net.
#
#========================================================================

use strict;
no  utf8;
use lib "/opt/local/backuppc/lib";
use File::Path;
use Getopt::Std;
use Encode qw/from_to/;
use IO::Handle;
use BackupPC::Lib;
use BackupPC::Attrib qw(:all);
use BackupPC::FileZIO;
use BackupPC::View;

die("BackupPC::Lib->new failed\n") if ( !(my $bpc = BackupPC::Lib->new) );
my $TopDir = $bpc->TopDir();
my $BinDir = $bpc->BinDir();
my %Conf   = $bpc->Conf();

my %opts;

if ( !getopts("te:h:n:p:r:s:", \%opts) || @ARGV < 1 ) {
    print STDERR <<EOF;
usage: $0 [options] files/directories...
  Required options:
     -h host         host from which you want to rebuild the directory
     -n dumpNum      dump number from which the rebuild is created
                     A negative number means relative to the end (eg -1
                     means the most recent dump, -2 2nd most recent etc).
     -s shareName    share name from which the rebuild

  Other options:
     -t              print summary totals
#     -r pathRemove   path prefix that will be replaced with pathAdd
#     -p pathAdd      new path prefix
     -e charset      charset for encoding file names (default: cp1252)
EOF
    exit(1);
}

if ( $opts{h} !~ /^([\w\.\s-]+)$/
        || $opts{h} =~ m{(^|/)\.\.(/|$)} ) {
    print(STDERR "$0: bad host name '$opts{h}'\n");
    exit(1);
}
my $Host = $opts{h};

if ( $opts{n} !~ /^(-?\d+)$/ ) {
    print(STDERR "$0: bad dump number '$opts{n}'\n");
    exit(1);
}
my $Num = $opts{n};

my @Backups = $bpc->BackupInfoRead($Host);
my $FileCnt = 0;
my $ByteCnt = 0;
my $DirCnt = 0;
my $SpecialCnt = 0;
my $ErrorCnt = 0;

my $i;
$Num = $Backups[@Backups + $Num]{num} if ( -@Backups <= $Num && $Num < 0 );
for ( $i = 0 ; $i < @Backups ; $i++ ) {
    last if ( $Backups[$i]{num} == $Num );
}
if ( $i >= @Backups ) {
    print(STDERR "$0: bad backup number $Num for host $Host\n");
    exit(1);
}

my $Charset = "cp1252";
$Charset = $opts{e} if ( $opts{e} ne "" );

my $PathRemove = $1 if ( $opts{r} =~ /(.+)/ );
my $PathAdd    = $1 if ( $opts{p} =~ /(.+)/ );
if ( $opts{s} =~ m{(^|/)\.\.(/|$)} ) {
    print(STDERR "$0: bad share name '$opts{s}'\n");
    exit(1);
}
my $ShareName = $opts{s};

my $BufSize    = 1048576;     # 1MB or 2^20
my(%UidCache, %GidCache);
my $fh = new IO::Handle;
$fh->fdopen(fileno(STDOUT),"w");

binmode(STDOUT);
foreach my $dir ( @ARGV ) {
    exportBackup($dir);
}

sub exportBackup
{
    my($dir, $pathOverride) = @_;

    my $view = BackupPC::View->new($bpc, $Host, \@Backups);

    if ( $dir =~ m{(^|/)\.\.(/|$)} || $dir !~ /^(.*)$/ ) {
        print(STDERR "$0: bad directory '$dir'\n");
        $ErrorCnt++;
        return;
    }
    $dir = "/" if ( $dir eq "." );
    $view->find($Num, $ShareName, $dir, 0, \&exportFiles, $pathOverride);
}

#
# print out totals if requested
#
if ( $opts{t} ) {
    print STDERR "Done: $FileCnt files, $ByteCnt bytes, $DirCnt dirs,",
                 " $SpecialCnt specials ignored, $ErrorCnt errors\n";
}
exit(0);

###########################################################################
# Subroutines
###########################################################################

sub UidLookup
{
    my($uid) = @_;

    $UidCache{$uid} = (getpwuid($uid))[0] if ( !exists($UidCache{$uid}) );
    return $UidCache{$uid};
}

sub GidLookup
{
    my($gid) = @_;

    $GidCache{$gid} = (getgrgid($gid))[0] if ( !exists($GidCache{$gid}) );
    return $GidCache{$gid};
}

my $Attr;
my $AttrDir;

sub exportFiles
{
    my($hdr, $pathOverride) = @_;

    my $tarPath = $hdr->{relPath};
    $tarPath = $pathOverride if ( defined($pathOverride) );

    if ( defined($PathRemove)
            && substr($tarPath, 0, length($PathRemove)) eq $PathRemove ) {
        substr($tarPath, 0, length($PathRemove)) = $PathAdd;
    }
    $tarPath = $1 if ( $tarPath =~ m{^\.?/+(.*)} );
    $tarPath =~ s{//+}{/}g;
    $hdr->{name} = $tarPath;
    return if ( $tarPath eq "." || $tarPath eq "./" || $tarPath eq "" );

    if ( $hdr->{type} == BPC_FTYPE_DIR ) {
        #
        # Directory: just make a directory
        #
        $hdr->{name} .= "/" if ( $hdr->{name} !~ m{/$} );
        from_to($hdr->{name}, "utf8", $Charset) if ( $Charset ne "" );
        mkdir($hdr->{name});
        $DirCnt++;
    } elsif ( $hdr->{type} == BPC_FTYPE_FILE ) {
        #
        # Regular file: open the file and write to the file
        #
        from_to($hdr->{name}, "utf8", $Charset) if ( $Charset ne "" );
        my $f = BackupPC::FileZIO->open($hdr->{fullPath}, 0, $hdr->{compress});
        if (!defined($f)) {
            print(STDERR "Unable to open file $hdr->{fullPath}\n");
            $ErrorCnt++;
            return;
        }

        open(out, ">$hdr->{name}") or return;

        binmode out;

        my $data;
        while ($f->read(\$data, $BufSize) > 0 and print(out $data)) { }
        $f->close;
        close(out);

        $FileCnt++;
        $ByteCnt += $hdr->{size};
    } elsif ( $hdr->{type} == BPC_FTYPE_HARDLINK ) {
        #
        # Hardlink file: create a hardlink
        #
        link($hdr->{fullPath}, $hdr->{name});
    } elsif ( $hdr->{type} == BPC_FTYPE_SYMLINK ) {
        #
        # Symlink: create a symlink
        #
        symlink($hdr->{fullPath}, $hdr->{name});

        $SpecialCnt++;
    } elsif ( $hdr->{type} == BPC_FTYPE_CHARDEV
           || $hdr->{type} == BPC_FTYPE_BLOCKDEV
           || $hdr->{type} == BPC_FTYPE_FIFO ) {
        #
        # Don't care...
        #
        $SpecialCnt++;
    } else {
        print(STDERR "Got unknown type $hdr->{type} for $hdr->{name}\n");
        $ErrorCnt++;
    }

    my $mtime = $hdr->{mtime};
    utime($mtime, $mtime, $hdr->{name});
    chmod($hdr->{mode}, $hdr->{name});
    chown($hdr->{uid}, $hdr->{gid}, $hdr->{name});
}
------------------------------------------------------------------------------
New Year. New Location. New Benefits. New Data Center in Ashburn, VA.
GigeNET is offering a free month of service with a new server in Ashburn.
Choose from 2 high performing configs, both with 100TB of bandwidth.
Higher redundancy.Lower latency.Increased capacity.Completely compliant.
http://p.sf.net/sfu/gigenet
_______________________________________________
BackupPC-devel mailing list
BackupPC-devel@lists.sourceforge.net
List:    https://lists.sourceforge.net/lists/listinfo/backuppc-devel
Wiki:    http://backuppc.wiki.sourceforge.net
Project: http://backuppc.sourceforge.net/

Reply via email to