X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-utils.git;a=blobdiff_plain;f=backup%2Fbackuplib.pl;h=8be8bff2cd91a889349377283ed119e6bde9884b;hp=d412c9400776e47dc40539cf40628e34e95e9209;hb=470ba2e9de232758429e7656cfecb18edffabbfa;hpb=3f7f507605d77ece782e847a5a1606197268f220 diff --git a/backup/backuplib.pl b/backup/backuplib.pl index d412c94..8be8bff 100644 --- a/backup/backuplib.pl +++ b/backup/backuplib.pl @@ -1,9 +1,35 @@ +# backuplib.pl +# core common routines # +# This file is part of chiark backup, a system for backing up GNU/Linux and +# other UN*X-compatible machines, as used on chiark.greenend.org.uk. +# +# chiark backup is: +# Copyright (C) 1997-1998,2000-2001 Ian Jackson +# Copyright (C) 1999 Peter Maydell +# +# This 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, or (at your option) any later version. +# +# This 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. + +require IO::File; sub printdate () { print scalar(localtime),"\n"; } +# Set status info -- we write the current status to a file +# so if we hang or crash the last thing written to the file +# will tell us where we were when things went pear-shaped. sub setstatus ($) { open S, ">this-status.new" or die $!; print S $_[0],"\n" or die $!; @@ -11,6 +37,8 @@ sub setstatus ($) { rename "this-status.new","this-status" or die $!; } +# startprocess, endprocesses, killprocesses are +# used to implement the funky pipeline stuff. sub startprocess ($$$) { my ($i,$o,$c) = @_; print LOG " $c\n" or die $!; @@ -23,6 +51,25 @@ sub startprocess ($$$) { exec $c; die "$c: $!"; } +sub readtapeid_raw () { + open T, ">>TAPEID" or die $!; close T; + unlink 'TAPEID' or die $!; + system "mt -f $tape rewind"; $? and die $?; + system "mt -f $tape setblk $blocksizebytes"; $? and die $?; + system "dd if=$tape bs=${blocksize}b count=10 ". + "| tar -b$blocksize -vvxf - TAPEID"; +} + +sub writetapeid ($) { + open T, ">TAPEID" or die $!; + print T "$_[0]\n" or die $!; + close T or die $!; + + system "tar -b$blocksize -vvcf TAPEID.tar TAPEID"; $? and die $?; + system "dd if=TAPEID.tar of=$ntape bs=${blocksize}b count=10"; + $? and die $?; +} + sub endprocesses () { while (keys %processes) { $p= waitpid(-1,0) or die "wait: $!"; @@ -42,28 +89,55 @@ sub killprocesses { undef %processes; } -sub readfsys ($) { - my ($fsnm) = @_; - open F, "$etc/fsys.$fsnm" or die "Filesystems $fsnm unknown ($!).\n"; +# Read a fsys.foo filesystem group definition file. +# Syntax is: empty lines and those beginning with '#' are ignored. +# Trailing whitespace is ignored. Lines of the form 'prefix foo bar' +# are handled specially, as arex lines 'exclude regexp'; otherwise +# we just shove the line into @fsys and let parsefsys deal with it. + +sub readfsysfile ($) { + my ($fn) = @_; + my ($fh,$sfn); + $fh= new IO::File "$fn", "r" or die "cannot open fsys file $fn ($!).\n"; for (;;) { - $_= or die; chomp; s/\s*$//; + $!=0; $_= <$fh> or die "unexpected EOF in $fn ($!)\n"; + chomp; s/\s*$//; last if m/^end$/; next unless m/\S/; next if m/^\#/; if (m/^prefix\s+(\w+)\s+(\S.*\S)$/) { $prefix{$1}= $2; - next; } elsif (m/^prefix\-df\s+(\w+)\s+(\S.*\S)$/) { $prefixdf{$1}= $2; - next; + } elsif (m/^excludedir\s+(\S.*\S)$/) { + push @excldir,$1; + } elsif (m/^exclude\s+(\S.*\S)$/) { + push @excl,$1; + } elsif (m/^include\s+(\S.*\S)$/) { + $sfn = $1; + $sfn =~ s/^\./fsys./; + $sfn = "$etc/$sfn" unless $sfn =~ m,^/,; + readfsysfile($sfn); + } else { + push @fsys,$_; } - push @fsys,$_; } - close F or die $!; + close $fh or die $!; +} + +sub readfsys ($) { + my ($fsnm) = @_; + my ($fsf); + $fsf= "$etc/fsys.$fsnm"; + stat $fsf or die "Filesystems $fsnm unknown ($!).\n"; + readfsysfile($fsf); } +# Parse a line from a filesystem definition file. We expect the line +# to be in $tf. sub parsefsys () { if ($tf =~ m,^(/\S*)\s+(\w+)$,) { + # Line of form '/file/system dumptype' $atf= $1; $tm= $2; $prefix= ''; @@ -71,6 +145,8 @@ sub parsefsys () { -d _ or die "not a dir: $atf"; $rstr= ''; } elsif ($tf =~ m,^(/\S*)\s+(\w+)\s+(\w+)$,) { + # Line of form '/file/system dumptype prefix' + # (used for remote backups, I think) $atf= $1; $tm= $2; $prefix= $3;