#
# DESCRIPTION
#
-# Usage: BackupPC_tarIncCreate [options] files/directories...
+# Usage: BackupPC_tarIncCreate [options]
#
# Flags:
# Required options:
#
# AUTHOR
# Craig Barratt <cbarratt@users.sourceforge.net>
+# Ivan Klaric <iklaric@gmail.com>
+# Dobrica Pavlinusic <dpavlin@rot13.org>
#
# COPYRIGHT
# Copyright (C) 2001-2003 Craig Barratt
use BackupPC::FileZIO;
use BackupPC::View;
use BackupPC::SearchLib;
-use Data::Dumper;
+use Time::HiRes qw/time/;
+use POSIX qw/strftime/;
+use Data::Dumper; ### FIXME
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 @DBCache;
-my $db_done = 0;
my %opts;
+my $in_backup_increment;
-if ( !getopts("th:n:p:r:s:b:w:", \%opts) || @ARGV < 1 ) {
+
+if ( !getopts("th:n:p:r:s:b:w:", \%opts) ) {
print STDERR <<EOF;
-usage: $0 [options] files/directories...
+usage: $0 [options]
Required options:
-h host host from which the tar archive is created
-n dumpNum dump number from which the tar archive is created
#
binmode(STDOUT);
my $fh = *STDOUT;
-if ( $ShareName eq "*" ) {
- my $PathRemoveOrig = $PathRemove;
- my $PathAddOrig = $PathAdd;
- foreach $ShareName ( $view->shareList($Num) ) {
- #print(STDERR "Doing share ($ShareName)\n");
- $PathRemove = "/" if ( !defined($PathRemoveOrig) );
- ($PathAdd = "/$ShareName/$PathAddOrig") =~ s{//+}{/}g;
- foreach my $dir ( @ARGV ) {
- archiveWrite($fh, $dir);
- }
- archiveWriteHardLinks($fh);
- }
+
+if (seedCache($Host, $ShareName, $Num)) {
+ archiveWrite($fh, '/');
+ archiveWriteHardLinks($fh);
} else {
- foreach my $dir ( @ARGV ) {
- archiveWrite($fh, $dir);
- }
- archiveWriteHardLinks($fh);
+ print STDERR "NOTE: no files found for $Host:$ShareName, increment $Num\n";
}
#
}
#
-# returns 1 if a given directory has files somewhere under it
-# in a given dump of a given share
+# seed cache of files in this increment
#
-sub checkSubDirs($$$$) {
- my ($dir, $share, $host, $dumpNo) = @_;
- my $ret;
+sub seedCache($$$) {
+ my ($host, $share, $dumpNo) = @_;
+
my $dsn = $Conf{SearchDSN};
my $db_user = $Conf{SearchUser} || '';
- my $search_sql;
- print(STDERR $dir);
- # erase first dot
- if (substr($dir, 0, 1) == '.')
- {
- $dir = substr($dir, 1, length($dir));
- }
- # erase first slash
- if (substr($dir, 0, 1) == '/')
- {
- $dir = substr($dir, 1, length($dir));
- }
- # erase last slash
- if (substr($dir, length($dir)-1, 1) == '/')
- {
- $dir = substr($dir, 0, length($dir)-1);
- }
-
- if (! $db_done)
- {
- print STDERR "doing db...";
- my $search_sql = q{
- SELECT hosts.name, shares.name, startfiles.name, COUNT(files.*) AS subfiles
- FROM files startfiles
- INNER JOIN shares ON (shares.id=startfiles.shareid)
- INNER JOIN hosts ON (hosts.id=shares.hostid)
- INNER JOIN backups ON (
- backups.num=startfiles.backupnum AND
- backups.hostid=hosts.id AND backups.shareid=shares.id
- )
- LEFT JOIN files ON (
- files.backupnum=startfiles.backupnum AND
- files.shareid=startfiles.shareid AND
- files.path LIKE startfiles.path || '/%' AND
- files.type<>startfiles.type AND
- files.id <> startfiles.id
- )
- WHERE
- hosts.name=? AND
- shares.name=? AND
- startfiles.type=? AND
- startfiles.backupnum=?
- GROUP BY hosts.name, shares.name, startfiles.name, startfiles.backupnum;
- };
- my $dbh = DBI->connect($dsn, $db_user, "", { RaiseError => 1, AutoCommit => 1} );
- my $sth = $dbh->prepare($search_sql);
- $sth->execute($host, $share, BPC_FTYPE_DIR, $dumpNo);
- print STDERR "done\n";
- while (my @r_data = $sth->fetchrow_array())
- {
- $DBCache[$r_data[0]][$r_data[1]][$r_data[2]] = 1;
- }
-
- $sth->finish();
-
- $DBCache[$host][$share][$dir] = $ret;
- $dbh->disconnect();
- $db_done = 1;
+ print STDERR curr_time(), "getting files for $host:$share increment $dumpNo...";
+ my $sql = q{
+ SELECT path
+ FROM files
+ JOIN shares on shares.id = shareid
+ JOIN hosts on hosts.id = shares.hostid
+ WHERE hosts.name = ? and shares.name = ? and backupnum = ?
+ };
+
+ my $dbh = DBI->connect($dsn, $db_user, "", { RaiseError => 1, AutoCommit => 1} );
+ my $sth = $dbh->prepare($sql);
+ $sth->execute($host, $share, $dumpNo);
+ my $count = $sth->rows;
+ print STDERR " found $count items\n";
+ while (my $row = $sth->fetchrow_arrayref) {
+print STDERR "+ ", $row->[0],"\n";
+ $in_backup_increment->{ $row->[0] }++;
}
+
+ $sth->finish();
+ $dbh->disconnect();
- if ($DBCache[$host][$share][$dir] != undef && $DBCache[$host][$share][$dir] == 1)
- {
- return 1;
- }
- return 0;
+ return $count;
}
my $Attr;
{
my($hdr, $fh, $tarPathOverride) = @_;
-
my $tarPath = $hdr->{relPath};
$tarPath = $tarPathOverride if ( defined($tarPathOverride) );
$tarPath =~ s{//+}{/}g;
+
+#print STDERR "? $tarPath\n";
+ return unless ($in_backup_increment->{$tarPath});
+print STDERR "A $tarPath\n";
+
if ( defined($PathRemove)
&& substr($tarPath, 0, length($PathRemove)) eq $PathRemove ) {
substr($tarPath, 0, length($PathRemove)) = $PathAdd;
$hdr->{name} .= "/" if ( $hdr->{name} !~ m{/$} );
- # check if it has files under it in the database
- if ( checkSubDirs($hdr->{path}, $ShareName, $Host, $Num) != 0 )
- {
- TarWriteFileInfo($fh, $hdr);
- $DirCnt++;
- }
+ TarWriteFileInfo($fh, $hdr);
+ $DirCnt++;
} elsif ( $hdr->{type} == BPC_FTYPE_FILE ) {
#
# Regular file: write the header and file
$hdr->{linkname} .= $data;
}
$f->close;
- #
- # Check @ARGV and the list of hardlinked files we have explicity
- # dumped to see if we have dumped this file or not
- #
my $done = 0;
my $name = $hdr->{linkname};
$name =~ s{^\./}{/};
if ( $HardLinkExtraFiles{$name} ) {
- $done = 1;
- } else {
- foreach my $arg ( @ARGV ) {
- $arg =~ s{^\./+}{/};
- $arg =~ s{/+$}{};
- $done = 1 if ( $name eq $arg || $name =~ /^\Q$arg\// );
- }
- }
- if ( $done ) {
#
# Target file will be or was written, so just remember
# the hardlink so we can dump it later.
$ErrorCnt++;
}
}
-
+
+my $t_fmt = '%Y-%m-%d %H:%M:%S';
+sub curr_time {
+ return strftime($t_fmt,localtime());
+}