#!/usr/bin/perl -Tw ################################################################################ # zzbackupz.pl = General Backup utility ################################################################################ # ver .001 = 11/14/2000 # Initial release hardcoaded to backup /var/spool/mail # ver .002 = 11/15/2000 # Made more configurable for general backups. # Selectable silent or verbose output # Selectable mail output mode ################################################################################ # This program is designed to make a set of backup archives of a user defined # list. These backups are then tarred together into a single archive and # compressed with gzip. # # The script can be set in either a verbose or silent mode. There is also an # option to email all messages using sendmail. These options allow you to make # backups from the commandline or using cron. # use strict; ################################################################################ # Variables ################################################################################ my $bkup_drive = "/dev/hdc4"; my $mnt_base = "/mnt"; my $tmp_base = "/tmp"; my $bkup_vol_chk = "bkup_media_chk"; my $unmount_drv = 0; # 1 = yes 0 = no # Get Todays date in the form mon-day-year: ex: jan-02-2000 my $todays_date = join '-', (( 'jan','feb','mar','apr','may', 'jun','jul','aug','sep','oct', 'nov','dec')[(localtime)[4]]), ((localtime)[3]), ((localtime)[5]+1900); my $archive_name = "backup-$todays_date"; my $tmp_dir = "$tmp_base/$archive_name"; my @msgs = (); ## Special Options my $msg_status = 1; # 1 = STDOUT 0 = SILENT my $mail_output = 0; # 1 = mail output using Sendmail 0 = dont mail ## Mail Settings my $email_to_addr = "your_email\@address.com"; my $email_to_name = "your name"; my $email_from_addr = "srvr_email\@address.com"; my $email_from_name = "zzbackupzz Backup Script"; ## Backup Data [ base_directory, archive_name, @files_to_archive ] my @bkups = ( [ "/home/zzspectrez", "zzspectrez-files.tar", "mail", "bin", "scripts","mp3s"], [ "/var/spool", "mail-spool.tar", "mail/zzspectrez", "mail/ghost", "mail/creep", "mail/spanky" ] ); my @done = (); # archive that were sucessfully backed up my $abn_exit = undef; $ENV{PATH} = "/bin:/usr/bin"; ################################################################################ # Subroutines ################################################################################ sub msg_handler (){ my $msg = shift; push @msgs, $msg; # store message print $msg if ($msg_status); # if not in silent mode print msg to stdout } sub last_msg (){ return $msgs[$#msgs]; #returns last message on the message stack } sub erase_dir (){ #safely erase the passed dir # returns undef if sucessful # else err_msg returned my $chk_name = shift; my $err_msg = undef; if (-e $chk_name) { if (-d $chk_name){ if (-l $chk_name){ $err_msg = "The directory [$chk_name] is a symbolic link to another directory.\n"; }else { system ('rm','-rf',$chk_name) == 0 or $err_msg = "The directory [$chk_name] was unable to be removed: $!\n"; } }elsif (-p $chk_name) { if (-l $chk_name){ $err_msg = "[$chk_name] is a symbolic or hard link to a plain file.\n"; }else { $err_msg = "[$chk_name] is a plain file.\n"; } }else{ $err_msg = "[$chk_name] is not a directory and is an unknown filetype.\n"; } }else{ $err_msg = "The directory [$chk_name] does not exist.\n"; } return $err_msg; } sub mail_msg { my $subj = shift; open (ML, "|/usr/lib/sendmail -oi -t") or die "Can't run sendmail!: $!\n"; print ML "From: $email_from_name <$email_from_addr>\n"; print ML "To: $email_to_name <$email_to_addr>\n"; print ML "Subject: $subj\n\n"; print ML @msgs; close (ML) or warn "Sendmail did not close properly.\n"; } ################################################################################ # Init and Cleanup Code ################################################################################ sub startup_init (){ #Create Temporary directory if (-e $tmp_dir){ if (my $err = &erase_dir($tmp_dir)){ &msg_handler ("Unable to properly remove directory: $err \n"); $abn_exit = &last_msg; &shutdown_cleanup; die "zzbackupz aborted.\n"; }else{ unless (mkdir($tmp_dir, 0755)){ &msg_handler("Unable to created directory [$tmp_dir]: $!\n"); $abn_exit = &last_msg; &shutdown_cleanup; die "zzbackupz aborted.\n"; } } }else{ unless (mkdir($tmp_dir, 0775)){ &msg_handler ("Unable to create directory [$tmp_dir]: $!\n"); $abn_exit = &last_msg; &shutdown_cleanup; die "zzbackupz aborted.\n"; } } #Check if backup drive mounted else mount it if (-e "$mnt_base/$bkup_vol_chk") { &msg_handler ("Backup media appears to allready be mounted.\n"); $unmount_drv = 0; # set status so we do not unmount on exit }else{ #Attempt to mount backup media if (system ('mount','-t','vfat',$bkup_drive,$mnt_base) == 0){ &msg_handler ("Backup media [$bkup_drive] was sucessfully mounted to [$mnt_base].\n"); $unmount_drv = 1; # unmount drive on exit }else{ &msg_handler ("Unable to mount backup media: $!\n"); $abn_exit = &last_msg; &shutdown_cleanup; die "zzbackupz aborted.\n"; } } } sub shutdown_cleanup (){ if ($abn_exit) { #End called due to abnormal exit &msg_handler ("Exiting backup due to abnormal exit: $abn_exit"); }else { &msg_handler ("Backup finished.\n"); } &msg_handler ("Removing temporary directory: [$tmp_dir].\n"); if (-e $tmp_dir){ if (my $err = &erase_dir($tmp_dir)){ &msg_handler ("Unable to properly remove directory: $err \n"); }else { &msg_handler ("[$tmp_dir] was removed.\n"); } } if ($unmount_drv) { &msg_handler ("Unmounting backup drive.\n"); if (system('umount',$mnt_base) == 0) { &msg_handler ("Sucessfully unmounted [$mnt_base].\n"); }else{ &msg_handler ("Unable to unmount [$mnt_base]: $!\n"); } }else{ &msg_handler ("Not attempting to unmount [$mnt_base]: Was mounted prior to backup or unable to mount.\n"); } &mail_msg("zzbackupz backup log for $todays_date") if $mail_output; } ########################################################### # Main Program ########################################################### &startup_init; foreach my $item ( @bkups ) { my ($base, $name, @files) = @$item; unless (chdir $base) { &msg_handler ("Skipped backup of [$name], could not change to directory [$base]: $!.\n"); next; } if (system("tar","-cf","$tmp_dir/$name",@files)) { &msg_handler ("The tar of [$name] did not complete sucessfully.\n"); next; }else { &msg_handler ("[$name] was sucesfully tarred.\n"); push @done, $name; } } if (@done) { unless (chdir $tmp_dir){ &msg_handler ("Unable to change to temp directory [$tmp_dir]:$!\n"); $abn_exit = &last_msg; &shutdown_cleanup; die "zzbackupz aborted.\n"; } if (system("tar","-cf",$archive_name,@done)){ &msg_handler ("The tar of [$archive_name] did not complete sucessfully.\n"); $abn_exit = &last_msg; &shutdown_cleanup; die "zzbackupz aborted.\n"; } if (system("gzip","-f9",$archive_name)){ &msg_handler ("The gzip of [$archive_name] did not complete sucessfully.\n"); $abn_exit = &last_msg; &shutdown_cleanup; die "zzbackupz aborted.\n"; } if (system("mv","$archive_name.gz",$mnt_base)){ &msg_handler ("Backup file was not sucessfully moved to zip drive.\n"); $abn_exit = &last_msg; &shutdown_cleanup; die "zzbackupz aborted.\n"; } }else { &msg_handler ("No files backed up.\n"); } &shutdown_cleanup;