Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Nov 10th, 2005, 2:31 PM   #11
Infinite Recursion
Programming Guru
 
Infinite Recursion's Avatar
 
Join Date: Jul 2004
Location: United States
Posts: 3,464
Rep Power: 8 Infinite Recursion is on a distinguished road
Send a message via MSN to Infinite Recursion Send a message via Yahoo to Infinite Recursion
Sounds good man...
__________________
http://jasonpowers.net

"There are a thousand hacking at the branches of evil to one who is striking at the root."
Infinite Recursion is offline   Reply With Quote
Old Nov 28th, 2005, 11:30 PM   #12
Infinite Recursion
Programming Guru
 
Infinite Recursion's Avatar
 
Join Date: Jul 2004
Location: United States
Posts: 3,464
Rep Power: 8 Infinite Recursion is on a distinguished road
Send a message via MSN to Infinite Recursion Send a message via Yahoo to Infinite Recursion
Piz's perl backup script works very well... I'm using it on my home network.

Here is a small script that I wrote that others that use his script may benefit from. It allows you to make an entry in the backup list, from anywhere in the filesystem, for files and directories that you want backed up.

./backit.sh (will send the current directory to the list)
./backit.sh source (will send "source" (file or dir) to the list)

#!/bin/sh

# backit.sh
# 28NOV2005 - Created.

# Adding file/directory to backup list in order to be backed up 
#   upon execution of Piz's Perl Backup script.


# User check (must be root)
userid=`whoami`
if [ $userid != "root" ]
then
        echo; echo "$0 must be executed as ROOT.  Aborted!"; echo;
        exit;
fi

# Usage / Syntax Check
if [ $# -gt 1 ]; then
   echo; echo;
   echo "Usage: $0 source"
   echo "   Where "source" is a file or directory to add to the backup list."
   echo "   $0 by itself will default to the current directory."
   echo; echo;
   exit;
fi

theDir=`pwd`
backupList="/backup/backup.dat"

if [ $# -eq 0 ] || [ $1 == "." ]
then
        # Directory Entry
        echo $theDir >> $backupList
        echo "Added $theDir to $backupList"
else 
        # File Entry
        theFile=$1
        echo $theDir/$theFile >> $backupList
        echo "Added $theDir/$theFile to $backupList"
fi
__________________
http://jasonpowers.net

"There are a thousand hacking at the branches of evil to one who is striking at the root."
Infinite Recursion is offline   Reply With Quote
Old Jan 8th, 2006, 10:25 PM   #13
Infinite Recursion
Programming Guru
 
Infinite Recursion's Avatar
 
Join Date: Jul 2004
Location: United States
Posts: 3,464
Rep Power: 8 Infinite Recursion is on a distinguished road
Send a message via MSN to Infinite Recursion Send a message via Yahoo to Infinite Recursion
# Modifications:
#
# 07 JAN 2006 - Infinite Recursion
# - Added ability to create iso from directory list.
# - Tweaked arg_check subroutine to accomodate iso creation.

Added CreateISO, this subroutine creates an ISO for all files specified in the list. Also, there is an interactive cdrecord option, to use uncomment.. May want to make a separate sub for the call to cdrecord if used in a non-interactive script.






#!/usr/bin/env perl

####################################################################################
# This perl script while not only being the first perl that i have ever written, it#
# will backup a list of directories by taring, bziping them, then creating md5   #
# check sums in order to check them later if i have to resote any of the files. #
####################################################################################

#
# Original Code:  Pizentios
#
# Modifications:
#
#       07 JAN 2006 - Infinite Recursion
#                - Added ability to create iso from directory list.
#                - Tweaked arg_check subroutine to accomodate iso creation.
#
# 

# --- Usage ---
#
# BACKUP
# ./backup.pl --backup --generate /backup/backup_04JAN06.restore --dir /backup/ --list /backup/backup.dat
# 
# RESTORE
# ./backup.pl --restore --list /backup/backup_04JAN06.restore
# 
# CHECK
# ./backup.pl --check --list /backup/backup_04JAN06.restore
# 
# CREATE ISO
#./backup.pl --list backup.dat --iso backup.iso


use 5.8.6;
use strict;
use Getopt::Long;
use IO::File;
use Archive::Tar;
use Digest::MD5;
use Cwd;


sub gen_arch_name 
{
        my $filename = $_[0]; #should only be passing just the locations of the file/dir to back up.
        my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time); #get info about the date, to gen the backup file names.
        $mon = $mon + 1; #human readable month.
        $year = $year + 1900; # human readable year.
        $filename=~ s/\//_/g; #replace all / with _
        $filename = reverse $filename; #reverse the file name so we can get rid of the leading _
        chop $filename; #get rid of the last _, which is really the first _
        $filename = reverse $filename; #get it back to the original filename, instead of backwards.
        my $arch_name = "$filename$year-$mon-$mday.tar.bz2";

        return $arch_name;

}

sub Check 
{
        my $list = $_[0]; #only ever one parm.
        my $md5 = Digest::MD5->new;
        my $check = 1;
        open(LIST, $list) or die "Error, can't open $list for reading. Please make sure that $list is there.";

        while (<LIST>) 
        {
                my ($file, $sum, $location) = split(/\|/, $_, 3); #split the line into stuff we can use.
                chomp $location;
                my $full_file = "$location/$file";

                #$full_file = substr($full_file,1,length($full_file)-1);

                open(FILE, $full_file) or die "Couldn't open $full_file for md5 checksum verification.";
                binmode(FILE);

                my $c_sum = $md5->addfile(*FILE)->hexdigest;

                close FILE;
                if ($c_sum ne $sum) 
                {
                        $check = 1;
                        last;
                } 
                else 
                {
                        $check = 0;
                }
        }
        return $check;
}

sub Backup 
{
        my ($list, $g, $d)  = @_;
        if ($g) 
        {
                #if the gen option is set, then we need to generate the restore file as well.
                # $g hold the location of were the file is to be outputed to.
                open(LIST, $list) or die "Error, can't open $list for reading. Please make sure that $list is there.";
                open(RES, ">>$g") or die "Error, can't open $g for writing. Please make sure that the path $g is there.";
                my $arch_name;
                my $md5 = Digest::MD5->new; #create the md5 object.
                while (<LIST>) 
                {
                        #loop and do stuff with the data.
                        chomp $_;
                        #make sure that it's not a symlink.
                        if ((-e $_) && (-s $_) && (! -l $_)) 
                        {
                                #we can continue.
                                #now tar and bzip the directory.
                                $arch_name = gen_arch_name($_); #correctly formatted backup name. 
                                system("tar -cjf $arch_name $_"); #tar and bz2 the directory.
                                #now to make the md5 check sum, and input the archive and the key into the output file that the user wanted.
                                #open the archive for md5 checksum generation.
                                open(FILE, $arch_name) or die "Couldn't open $arch_name for md5 checksum generation."; 
                                binmode(FILE);
                                my $sum = $md5->addfile(*FILE)->hexdigest; #create and store the md5 checksum in the var $sum.
                                close FILE;
                                #k, now we have the checksum, dump the archive file name and the checksum into the output file, if it's enabled.
                                if ($d) 
                                {
                                        #print the archive name, the checksum and the backup location to the restore file.
                                        print RES "$arch_name|$sum|$d\n"; 
                                        #now to move the tar.bz2's to the backup directory.
                                        system("mv $arch_name $d");
                                } 
                                else 
                                {
                                        my $c_dir = getcwd;
                                        print RES "$arch_name|$sum|$c_dir\n"; #print the archive name, the checksum and the current working directory since that's were the backs are going to get stored.
                                }
                        } #else do nothing.
                }
                close LIST;
                close RES;
                #now check all files in the restore file, against a new md5 checksum, to make sure that it's all good.
                my $check = Check($g);
                if ($check == 0)
                {
                        #check works, let the user know.
                        print "All file checksums check out.\n";
                } 
                else 
                {
                        print "One or more checksums do not check out.\n";
                }
        } 
        else 
        {
                #do not generate teh restore file.
                open(LIST, $list) or die "Error can't open $list for reading. Please make sure that $list is there.\n";

                while(<LIST>) 
                {
                        chomp $_;
                        if ((-e $_) && (-s $_) && (! -l $_)) 
                        {
                                my $arch_name = gen_arch_name($_); #correctly formated archive name.
                                system("tar -cjf $arch_name $_"); #tar and bz2 the dir/file.
                                if ($d) 
                                {
                                        system("mv $arch_name $d");
                                }
                        }
                }
                close LIST;
        }
}

sub Restore 
{
        my $list = $_[0]; #should only ever be one parm.
        my $check = Check($list);
        if ($check == 0) 
        {
                open(LIST, $list) or die "Error, can't open $list for reading. Please make sure that $list is there.\n";

                while (<LIST>) 
                {
                        my ($file, $sum, $location) = split(/\|/, $_, 3);
                        chomp $location;
                        my $file_l = "$location/$file"; #the current location of the file we are going to restore.
                        my $restore_p = $file;
                        $restore_p =~ s/_/\//g; #replace the _ with /
                        $restore_p =~ s/(\d\d\d\d)-(\d+)-(\d+).tar.bz2//g;
                        #now we have the correct restore point.
                        #however we still need to handle single files correctly.
                        my $len = length($restore_p);
                        my $offset = $len - 1;
                        my $check = substr($restore_p, $offset, 1);
                        if ($check ne "/") 
                        {
                                #we are working with a single file. Strip the last part of the location off, since we only need the directories.
                                $restore_p = reverse $restore_p;
                                my @path = split(//, $restore_p);
                                my ($i, $word);
                                for ($i=0; $i<$len; $i++) 
                                {
                                        if (@path[$i] ne "/") 
                                        {
                                                $word = "$word@path[$i]";
                                        } 
                                        else 
                                        {
                                                last;
                                        }
                                }
                                $word = reverse $word;
                                $restore_p = reverse $restore_p;
                                $restore_p =~ s/$word//g;
                                $restore_p= "/$restore_p";
                        } #else we are working with a directory and need to change nothing.
                        system ("tar -xvjf $file_l -C /");
                }
                close LIST;
        } 
        else 
        {
                print "Error, one or more of your backups might be bad or have been tampered with. Checksums do not match!!!";
        }
}

######################################################################################
# CreateISO:  This subroutine creates an ISO for all files specified in the list.
#                                 Also, there is an interactive cdrecord option, to use uncomment.
#                                 May want to make a separate sub for cdrecord if used in script.
#                                 - Jason Powers
######################################################################################
sub CreateISO
{
    my ($list, $iso, $d)  = @_;
    my $dirlist;

    open (DATAFILE,$list);
    while (<DATAFILE>)
    {
        chomp;
        print "Adding $_ to iso file...\n";
        $dirlist = $dirlist . " " . $_;
    }

    system("mkisofs -l -o $iso $dirlist 2> /dev/null");
    print ("ISO created as: $iso\n");

   # Interactive CD Burn... Uncomment for usage, or run cdrecord manually.
   #
   # print ("Burn ISO to a CD? ");
   #
   # my $burn = <STDIN>;
   # $burn = chomp($burn);
   #
   # if (($burn == "y" ) || ($burn == "Y"))
   # {
   #    print("Burning ISO content to CD...\n");
   #    system("cdrecord -dev ATAPI:/dev/hdc -data $iso");
   # }
   # else
   # {
   #    print ("ISO not burned to CD at user's request.\n");
   # }
}


sub arg_check 
{
        #Check the arguments.
        my ($b, $c, $r, $i) = @_; #grab the sub args, then assign them.
        my $answer = 0; #set answer to 0
        if ($b) 
        {
                $answer = $answer + 1;
        }

        if ($c) 
        {
                $answer = $answer + 1;
        }

        if ($r) 
        {
                $answer = $answer + 1;
        }

        if ($i)
   {
       $answer = $answer + 1;
   }

        if ($answer > 1) 
        {
                #if answer is larger than 1, then the user has set to options that don't belong.
                #return failure. else the user has the right options.
                return 1;
        } 
        else 
        {
                return 0;
        }
}
#Use getops to parse the stuff the user passes to us.
my ($l_location, $check, $backup, $restore, $gen, $dir, $iso);
GetOptions("list=s" => \$l_location, #the location of the list we want to backup.
         "check" => \$check, #if the user wants to run a check on a set of backups, defined in $l_location.
           "backup" => \$backup, #if the user wants to backup the files listed in the file in $l_location. 
           "restore"=> \$restore, #if the user want to restore the files listed in the file in $l_location.
         "generate=s"=> \$gen, #if enabled, generate a resotre file, instead of just outputing to the screen.
         "dir=s"        => \$dir, #the location of the directory where the backups will be placed. If there is no dir option set, the current working directory will be used.
        "iso=s" => \$iso,  #the iso file
           );

die "Error, you must supply a file/directory listing with the list option!" unless defined $l_location;
if ($backup || $check || $restore || $iso) 
{
        my $arg_c = arg_check($check, $backup, $restore, $iso);
        if ($arg_c == 1) 
        {
                #error, more switches have been set than needed.
                die "Error, you have supplied more command options that needed!";
        } 
        else 
        {
                #there is only one command option set.
                if ($backup) 
                {
                        #backup proceedure.
                        Backup($l_location, $gen, $dir);
                } 
                elsif ($check) 
                {
                        #check proceedure.
                        my $check = Check($l_location);
                        if ($check == 0)
                        {
                                #checked out.
                                print "All checksums check out.\n";
                        } 
                        else 
                        {
                                print "One or more of the checksums don't check out.\n";
                        }
                } 
                elsif ($restore) 
                {
                        #restore proceedure.
                        Restore($l_location);
                }
                elsif ($iso)
                {
                        CreateISO($l_location,$iso,$dir);
                }
        }
} 
else 
{
        die "Error, you must set atleast one command option!";
}
__________________
http://jasonpowers.net

"There are a thousand hacking at the branches of evil to one who is striking at the root."
Infinite Recursion is offline   Reply With Quote
Old Jan 9th, 2006, 9:13 AM   #14
Pizentios
Programming Guru
 
Pizentios's Avatar
 
Join Date: May 2004
Location: Brandon, Manitoba, Canada
Posts: 2,023
Rep Power: 7 Pizentios is on a distinguished road
Send a message via ICQ to Pizentios Send a message via MSN to Pizentios
Lookin' good!

definatly a feature that can use :-)

It's always good to have a hard copy of your data, offsite if possible.
__________________
Profanity is the one language that all programmers understand.

Check out my Blog <---updated Nov 30 2007!
Pizentios is offline   Reply With Quote
Old Jan 9th, 2006, 9:55 AM   #15
Infinite Recursion
Programming Guru
 
Infinite Recursion's Avatar
 
Join Date: Jul 2004
Location: United States
Posts: 3,464
Rep Power: 8 Infinite Recursion is on a distinguished road
Send a message via MSN to Infinite Recursion Send a message via Yahoo to Infinite Recursion
Yeah, I was wanting to throw in a SCP to a remote system as well. (I have a secondary script that does this already, plus burns a cd). Will implement an SCP call when I throw in the CD creation code.

Right now, the creation of the cd is commented out as it is user interactive and needed to be part of a cron job. I will look into putting the call to burn a cd in as a optional parameter to the script.

Meanwhile, to burn a cd of the iso that was created via the -iso option execute this...

cdrecord -dev ATAPI:/dev/hdc -data filename.iso
__________________
http://jasonpowers.net

"There are a thousand hacking at the branches of evil to one who is striking at the root."
Infinite Recursion is offline   Reply With Quote
Old Jan 9th, 2006, 11:52 AM   #16
Pizentios
Programming Guru
 
Pizentios's Avatar
 
Join Date: May 2004
Location: Brandon, Manitoba, Canada
Posts: 2,023
Rep Power: 7 Pizentios is on a distinguished road
Send a message via ICQ to Pizentios Send a message via MSN to Pizentios
currently working on adding a feature to login to remote boxes and do a backup. That means you can have a centrailized backup solution! Also, i will be making it able to mount network shares to back them up as well.
__________________
Profanity is the one language that all programmers understand.

Check out my Blog <---updated Nov 30 2007!
Pizentios is offline   Reply With Quote
Old Jan 11th, 2006, 10:56 AM   #17
Infinite Recursion
Programming Guru
 
Infinite Recursion's Avatar
 
Join Date: Jul 2004
Location: United States
Posts: 3,464
Rep Power: 8 Infinite Recursion is on a distinguished road
Send a message via MSN to Infinite Recursion Send a message via Yahoo to Infinite Recursion
If you use the CreateISO feature of this script, you will need to replace the existing CreateISO function with this one:

sub CreateISO
{
    my ($list, $iso, $d)  = @_;
    my $dirlist;

    open (DATAFILE,$list);
    while (<DATAFILE>)
    {
        chomp $_;
        if ((-e $_) && (-s $_) && (! -l $_))
        {
            print "Adding $_ to iso file...\n";
            $dirlist = $dirlist . " " . $_;
        }
    }

   system("mkisofs -l -o $iso $dirlist 2> /dev/null");

   open(FILE, $isoFile) or die "Unable to create iso file, check $datFile content for invalid entries.";

    print ("ISO created as: $iso\n");

   # Interactive CD Burn... Uncomment for usage, or run cdrecord manually.
   #
   # print ("Burn ISO to a CD? ");
   #
   # my $burn = <STDIN>;
   # $burn = chomp($burn);
   #
   # if (($burn == "y" ) || ($burn == "Y"))
   # {
   #    print("Burning ISO content to CD...\n");
   #    system("cdrecord -dev ATAPI:/dev/hdc -data $iso");
   # }
   # else
   # {
   #    print ("ISO not burned to CD at user's request.\n");
   # }
}
__________________
http://jasonpowers.net

"There are a thousand hacking at the branches of evil to one who is striking at the root."
Infinite Recursion is offline   Reply With Quote
Old Jan 12th, 2006, 10:35 AM   #18
bobfox
Newbie
 
Join Date: Aug 2005
Posts: 17
Rep Power: 0 bobfox is on a distinguished road
cool!

Last edited by bobfox; Jan 12th, 2006 at 10:46 AM.
bobfox is offline   Reply With Quote
Old Jan 12th, 2006, 10:50 AM   #19
Infinite Recursion
Programming Guru
 
Infinite Recursion's Avatar
 
Join Date: Jul 2004
Location: United States
Posts: 3,464
Rep Power: 8 Infinite Recursion is on a distinguished road
Send a message via MSN to Infinite Recursion Send a message via Yahoo to Infinite Recursion
Here is the BurnCD subroutine for those who want to use it within the main script.

The subroutine takes two arguments, the name of the device and the iso file to burn.
For example: BurnCD("0,0,0","example.iso");

If you are not sure of your device name for the cd recorder, run 'cdrecord -scanbus' as root.

Quote:
Cdrecord 2.0 (i686-pc-linux-gnu) Copyright (C) 1995-2002 J?rg Schilling
Linux sg driver version: 3.1.24
Using libscg version 'schily-0.7'
scsibus0:
0,0,0 0) 'HL-DT-ST' 'CD-RW GCE-8400B ' 'B104' Removable CD-ROM
0,1,0 1) *
0,2,0 2) *
0,3,0 3) *
0,4,0 4) *
0,5,0 5) *
0,6,0 6) *
0,7,0 7) *

My burner is located on device 0,0,0...


###################################################################################
# BurnCD: This subroutine burns a CD using the ISO created in the CreateISO subroutine.
# - Jason Powers
###################################################################################
sub BurnCD
{
my ($dev, $iso) = @_;
 
print "Dev: $dev\n";
print "Iso: $iso\n";
 
open(FILE, $iso) or die "Unable to burn iso file to cd...";
 
system("cdrecord -dev $dev -data $iso");
}
__________________
http://jasonpowers.net

"There are a thousand hacking at the branches of evil to one who is striking at the root."
Infinite Recursion is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 2:52 AM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC