#!/usr/bin/perl use warnings; use strict; # OMIT: initialize some useful variables... # Here everything gets called. These subroutines are defined below. _log _begin; $settings = read_config("/etc/backup.conf"); create_archive($settings->{archive}); upload_archive($settings->{FTP}); tape_archive($settings->{tape}); delete_temp_files(); _log _end; # # send the files to tape. We use the rewinding device, because we # don't really care about putting several archives on the same tape. # We also eject the tape because we want a different tape for each # day of the week. sub tape_archive { my $conf = shift or return; # are we configured to tape stuff? my ($rdev, @tapeables) = ($conf->{'rdev'}, @{$conf->{'tapeables'}}); push @tapeables, $tarball if ($settings->{'archive'}); # With the tape out, the following ought to _barf. But it doesn't. undef $!; system("tar --ignore-failed-read -cf $rdev @tapeables") and _barf "couldn't write to tape. Error $? : $! "; # Even if the previous line doesn't _barf, surely this one must, # right? Wrong. undef $!; system("mt -f $rdev offline") and _barf "couldn't eject tape. Error $? : $! "; push @deleteables, @tapeables; } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Below this point are housekeeping and logging subs, so # # feel free to skip to the bottom # # logging subs sub _begin { chomp (my $now = `date`); return "-----\nstarting backup on $hostname at $now \n"; } sub _log { # OMIT: log stuff to file and return what was logged } sub _barf { my $msg = _log shift() .$/. _end(); _mail( $settings->{mail}, $msg); die $msg; } sub _mail { my $conf = shift or return; # are we configured to mail stuff? use Net::SMTP; # OMIT: mail errors to the admin } sub _end { chomp (my $now = `date`); return "ended at $now \n-----\n"; } # Read in the config file using Parse::PlainConfig sub read_config { use Parse::PlainConfig; # OMIT: read settings from file and return a hashref } sub is_true($) { # used by read_config return defined $_[0] && $_[0] !~ /^(false|no|0)$/; } sub create_archive { # The first step is to create a temporary archive in /tmp/. # OMIT: we're writing to file. No problem here. } sub dump_into_file { # OMIT: turn the list of sources into an array we can send to tar } sub upload_archive { # OMIT: irrelevant } sub delete_temp_files { # clean up our temp directory. # OMIT: housekeeping code } __END__