#!/usr/bin/perl -w
use strict;
use Tk;
use Tk::Dialog;
use Tk::HList;
use Tk::ProgressBar;
use Tk::NoteBook;
use warnings;
use Time::Local;
use Shell qw(robocopy);
use Tk::DirTree;
use Win32::DirSize;#calculate the size of a directory or how much space is available on a directory
use Math::Round;
use File::Basename;
#-----------------------Global variables------------------------------
my %gGui; #create an associative array also called hash
$gGui{per}=my $per=0;#hold the percent of the source in relation with the destination drive
$gGui{sbyteoriginal}=my $sbyteoriginal=0;#hold the original value of the total of the source to calculate the fudge factor
$gGui{value}= my $value="1"; # holds the value of the radio buttons
$gGui{dest} = my $dest=""; #holds the destination path
$gGui{source} = my $source=""; #holds the source path
$gGui{logpath} = my $logpath=""; #holds the path where the logs from Robocopy file will be saved
$gGui{logname} = my $logname=""; #holds the name of the file for a single collection
$gGui{complog} = my $complog=""; #holds the name of the comprehensive log
$gGui{complogpath} = my $complogpath="";#holds the name of the path for the comprehensive file
$gGui{lswitch} = 0; #holds 1 or 0 depending if the checkbutton is checked
$gGui{sswitch} = 0; #holds 1 or 0 depending if the checkbutton is checked
$gGui{eswitch} = 0; #holds 1 or 0 depending if the checkbutton is checked
$gGui{xfswitch} = 0; #holds 1 or 0 depending if the checkbutton is checked
$gGui{fileentry} = my $fileentry="*.*"; #holds *.* names of files to act upon
$gGui{xfentry} = my $xfentry=""; #holds the extensions of the files to exclude--if more than 1, separated by commas
$gGui{xdswitch} = 0; #holds 1 or 0 depending if the checkbutton is checked
$gGui{xdentry} = my $xdentry=""; #holds the directory to exclude--if more than 1, separated by commas
$gGui{wswitch} = 0; #holds 1 or 0 depending if the checkbutton is checked
$gGui{wentry} = 3; #holds the numerical user input--3 second is the default
$gGui{rswitch} = 0; #holds 1 or 0 depending if the checkbutton is checked
$gGui{rentry} = 3; #holds the user input-- 3 retry is the default
$gGui{copyentry} = my $copyentry=""; #holds the user input --DATSOU
$gGui{single} = 0; #allows to check if the single radio button is selected
$gGui{batchb} = 1; #allows to check if the batch radio button is selected
$gGui{fpswitch} = 0; #holds 1 or 0 depending if the checkbutton is checked
$gGui{tsswitch} = 0; #holds 1 or 0 depending if the checkbutton is checked
$gGui{destinationsize} = my $destinationsize=""; #holds the numerical size returned from perl
$gGui{sourcesize} = my $sourcesize=""; #holds the size variable for the source path
$gGui{sourcesizecal} = 0; #hold if the user wants to have FriendlyRoboCopy calculate the size of the source folder
$gGui{investigator_name} = my $investigator_name="";#holds the investigator name
$gGui{investigator_co_name} = my $investigator_co_name="";#holds the investigator company name
$gGui{investigator_co_add} = my $investigator_co_add=""; #holds the investigator compnay address
$gGui{investigator_co_phone} = my $investigator_co_phone="";#holds the investigator phone number
$gGui{case_number} = my $case_number=""; #holds the case number
$gGui{network_share} = my $network_share=""; #holds the network share information
$gGui{hard_drive} = my $hard_drive=""; #holds the hard drive information
$gGui{system_serial} = my $system_serial=""; #holds the examined system serial number
$gGui{reason} = my $reason=""; #holds the reason for examination
$gGui{case_name} = my $case_name=""; #holds the name of the company been examined
$gGui{case_info} = my $case_info=""; #holds the name and address of client
$gGui{message} = my $message=""; #holds the general comments
$gGui{sourcetext} = my $sourcetext=""; #holds the user name and full name of the folders in textarea on thrid tab
$gGui{dbyte} = 0; #holds the space available
$gGui{sbyte} = 0; #holds the size of the source
$gGui{switches} = my $switches=""; #holds the switches
$gGui{original_source} = my $original_source = "\""; #holds the original written directory for the source
$gGui{original_dest} = my $original_dest = "\""; #holds the original written directory for the destination
$gGui{original_path} = my $original_path = "\"";#holds the original written directory for the log file path
my @arraybatch; #hold the directory from the batch file
my @arrayfilename; #hold the odd elements from the text file -- the full name
my @arraydirectory; #hold the even elements from the text file -- the directory name
my @array; #holds the data from the file for error checking
my @arrayfile; #holds the path and file name for the error reporting
my $user =""; #holds each user name as it reads the array @arrayfilename
my $file =""; #holds the name of the file that is being processed during the error report
#-------------date------------------------------------------------
my $mday=(localtime)[3];
my $mon=(localtime)[4];
my $year=(localtime)[5];
$mon=$mon + 1;
$year=$year+1900;
my $date = "Today's Date: ";
$date .="$mon/$mday/$year";
my $mw=MainWindow->new();
$mw->minsize(qw(545 470));
$mw->title("FRIENDLYROBOCOPY ");
$mw->configure(-background=>'lightblue');
requirements();#check to see if all the requirements are met
my $menu=$mw->Menubutton (
-text=>'HELP',
-font=>"Times 11",
-background=>'lightblue',
-foreground=>'blue',
-activebackground=>'cyan',
-activeforeground=>'blue',
-menuitems=>[ [ 'command' => "User's Guide to FriendlyRoboCopy",
"-command" => \&help,
"-underline" => 0],
[ 'command' => "RoboCopy Documentation",
"-command" => \&robo,
"-underline" => 0],
[ 'command' => "About FRIENDLYROBOCOPY",
"-command" => \&about,
"-underline" => 0 ] ])->pack(-anchor => 'ne');
my $notebook=$mw->NoteBook(-font=>"Helvetica 12")->pack(-expand => 1, -fill => 'both');
my $page1=$notebook->add('page1', -label=>'Case Information');
#---------------------First Tab--information------------------------
my $generall=$page1->Label(-text=>'GENERAL INFORMATION', -font=>"Times 12")->place(-x=>160, -y=>2);
my $investigation_datel=$page1->Label(-textvariable=>\$date)->place(-x=>10, -y=>30);
my $staronel=$page1->Label(-text=>'*', -foreground=>'red')->place(-x=>430, -y=>1);
my $double_starl=$page1->Label(-text=>'= Default Field')->place(-x=>440, -y=>1);
my $investigator_namel=$page1->Label(-text=>'*Examiner Name', -foreground=>'red')->place(-x=>10, -y=>60);
my $investigator_nametf=$page1->Entry(-textvariable=>\$gGui{investigator_name},-width=>23)->place(-x=>110, -y=>60);
my $investigator_co_namel=$page1->Label(-text =>'*Company Name', -foreground=>'red')->place(-x=>10, -y=>90);
my $investigator_co_nametf=$page1->Entry(-textvariable=>\$gGui{investigator_co_name},-width=>23)->place(-x=>110, -y=>90);
my $investigator_co_addl=$page1->Label(-text=>'*Company Address', -foreground=>'red')->place (-x=>10, -y=>120);
my $investigator_co_addtf=$page1->Entry(-textvariable=>\$gGui{investigator_co_add},-width=>23)->place(-x=>110, -y=>120);
my $investigator_co_phonel=$page1->Label(-text=>'*Company Phone', -foreground=>'red')->place(-x=>10, -y=>150);
my $investigator_co_phonetf=$page1->Entry(-textvariable=>\$gGui{investigator_co_phone},-width=>23)->place(-x=>110, -y=>150);
my $case_numberl=$page1->Label(-text=>'Case #', -foreground=>'red')->place(-x=>10, -y=>180);
my $case_numbertf=$page1->Entry(-textvariable=>\$gGui{case_number},-width=>23)->place(-x=>110, -y=>180);
my $case_namel=$page1->Label(-text=>'Case Name', -foreground=>'red')->place(-x=>10, -y=>210);
my $case_nametf=$page1->Entry(-textvariable=>\$gGui{case_name},-width=>23)->place(-x=>110, -y=>210);
my $reasonl=$page1->Label(-text=>'Reason to Collect', -foreground=>'red')->place(-x=>10, -y=>240);
my $reasontf=$page1->Entry(-textvariable=>\$gGui{reason}, -width=>23)->place(-x=>110, -y=>240);
my $case_infol=$page1->Label(-text=>'Company Info', -foreground=>'red')->place(-x=>10, -y=>270);
my $case_infotf=$page1->Entry(-textvariable=>\$gGui{case_info}, -width=>23)->place(-x=>110, -y=>270);
my $complogl=$page1->Label(-text=>'COMPREHENSIVE LOG FILE INFO', -font=>"Times 10")->place(-x=>295, -y=>30);
my $complognamel=$page1->Label(-text=>'Name', -foreground=>'red')->place(-x=>280, -y=>60);
my $complognametf=$page1->Entry(-textvariable=>\$gGui{complog}, -width=>20, -validate=>'key',
-validatecommand=>sub{$_[1]=~ /^[_ a-zA-Z0-9]?$/}, -invalidcommand=>sub{$page1->bell})->place(-x=>320, -y=>60);
my $complogpathl=$page1->Label(-text=>'Folder Path', -foreground=>'red')->place(-x=>280, -y=>90);
my $complogpathb=$page1->Button(-text=>'Browse [...]', -command=>\&comp_log_dir_select, -foreground=>'blue', -activeforeground=>'blue')->place(-x=>360, -y=>90);
my $complogpathtf=$page1->Label(-textvariable=>\$gGui{complogpath}, -wraplength=>250, -justify=>'left')->place(-x=>280, -y=>120);
my $system_infol=$page1->Label(-text=>'SYSTEM INFORMATION', -font=>"Times 10")->place(-x=>320, -y=>180);
my $network_sharel=$page1->Label(-text=>'Network Share Info')->place(-x=>280, -y=>210);
my $network_sharetf=$page1->Entry(-textvariable=>\$gGui{network_share},-width=>20)->place(-x=>380, -y=>210);
my $hard_drivel=$page1->Label(-text=>'Hard Drive Info')->place(-x=>280, -y=>240);
my $hard_drivetf=$page1->Entry(-textvariable=>\$gGui{hard_drive},-width=>20)->place(-x=>380, -y=>240);
my $system_seriall=$page1->Label(-text=>'System Serial #')->place(-x=>280, -y=>270);
my $system_serialtf=$page1->Entry(-textvariable=>\$gGui{system_serial},-width=>20)->place(-x=>380, -y=>270);
my $messagel=$page1->Label(-text=>'General Comments', -wraplength=>50, -justify=>'left')->place(-x=>20, -y=>300);
my $messagetf=$page1->Scrolled('Text', -scrollbars=>'e', -width=>50, -height=>4)->place(-x=>80, -y=>300);
my $clear1=$page1->Button(-text=>'CLEAR', -command=>\&clearfirst)->place(-x=>10, -y=>350);
my $next1=$page1->Button(-text=>'NEXT', -command=>\&gotoswitches, -foreground=>'blue', -activeforeground=>'blue')->place(-x=>480, -y=>350);
#---------------------------------Second tab -- Switches-------------------------------------
my $page2=$notebook->add('page2', -label=>'Switches');
my $switchl=$page2->Label(-text=>'Check ALL Applicable Switches', -font=>"Times 13")->place(-x=>150, -y=>2);
my $lcb=$page2->Checkbutton(-text=>'/L', -variable=>\$gGui{lswitch}, -font=>"Adobe 10", -wraplength=>200)->place(-x=>10, -y=>30);
my $ll=$page2->Label(-text=>'Lists files without copying or applying a time stamp to any files', -wraplength=>95, -justify=>'left')->place(-x=>60, -y=>30);
my $scb=$page2->Checkbutton(-text=>'/S', -variable=>\$gGui{sswitch}, -font=>"Adobe 10")->place(-x=>280, -y=>30);
my $sl=$page2->Label(-text=>'Copies subdirectories', -justify=>'left')->place(-x=>340, -y=>35);
my $ecb=$page2->Checkbutton(-text=>'/E', -variable=>\$gGui{eswitch}, -font=>"Adobe 10")->place(-x=>280, -y=>65);
my $el=$page2->Label(-text=>'Copies all subdirectories, including empty ones', -wraplength=>170, -justify=>'left') ->place(-x=>340, -y=>65);
my $canvas1=$page2->Canvas(-background=>'black', -width=>350, -height=>2)->place(-x=>70, -y=>98);
my $copyallcb=$page2->Radiobutton(-text=>'/COPYALL', -variable=>\$gGui{value}, -font=>"Adobe 10", -value=>1)->place(-x=>10, -y=>110);
my $copyalll=$page2->Label(-text=>'Copies everything. Equivalent to /COPY:DATSOU', -wraplength=>140, -justify=>'left')->place (-x=>110, -y=> 110);
my $seccb=$page2->Radiobutton(-text=>'/SEC', -variable=>\$gGui{value}, -font=>"Adobe 10", -value=>2)->place(-x=>10, -y=>155);
my $secl=$page2->Label(-text=>'Copies NTFS security information. Equivalent to /COPY:DATS (Source and destination volumes must both be NTFS)', -wraplength=>160, -justify=>'left')->place(-x=>75, -y=>155);
my $copycb=$page2->Radiobutton(-text=>'/COPY', -variable=>\$gGui{value},-font=>"Adobe 10", -value=>3)->place(-x=>280, -y=>110);
my $copytf=$page2->Entry(-textvariable=>\$gGui{copyentry}, -validate=>'key',
-validatecommand=>sub{$_[1]=~ /^[aAdDtTsSoOuU]?$/},
-invalidcommand=>sub{$page2->bell})->place(-x=>360, -y=>112);
my $copyl=$page2->Label(-text=>'Copies the file information specified by copyflags, which can be any combination of the following:', -wraplength=>230, -justify=>'left')->place(-x=>280, -y=> 135);
my $copydl=$page2->Label(-text=>'D - file Data', -justify=>'left')->place(-x=>280, -y=>170);
my $copyal=$page2->Label(-text=>'A - file Attributes', -justify=>'left')->place(-x=>280, -y=>190);
my $copytl=$page2->Label(-text=>'T - file Timestamps', -justify=>'left')->place(-x=>280, -y=>210);
my $copysl=$page2->Label(-text=>'S - file Security (NTFS ACLs)', -justify=>'left')->place(-x=>370, -y=>170);
my $copyol=$page2->Label(-text=>'O - file Ownership info', -justify=>'left')->place(-x=>385, -y=>190);
my $copyul=$page2->Label(-text=>'U - file aUditing info', -justify=>'left')->place(-x=>400, -y=>210);
my $canvas2=$page2->Canvas(-background=>'black', -width=>350, -height=>2)->place(-x=>70, -y=>233);
my $xfcb=$page2->Checkbutton(-text=>'/XF', -variable=>\$gGui{xfswitch}, -font=>"Adobe 10")->place(-x=>10, -y=>250);
my $xftf=$page2->Entry(-textvariable=>\$gGui{xfentry}, -width=>18)->place(-x=>60, -y=>253);
my $xfl=$page2->Label(-text=>'Excludes files', -justify=>'left')->place (-x=>180, -y=>253);
my $xdcb=$page2->Checkbutton(-text=>'/XD', -variable=>\$gGui{xdswitch}, -font=>"Adobe 10")->place(-x=>10, -y=>280);
my $xdtf=$page2->Entry(-textvariable=>\$gGui{xdentry}, -width=>18)->place(-x=>60, -y=>283);
my $xdl=$page2->Label(-text=>'Excludes directories', -justify=>'left')->place (-x=>180, -y=>283);
my $tscb=$page2->Checkbutton(-text=>'/TS', -variable=>\$gGui{tsswitch}, -font=>"Adobe 10")->place(-x=>280, -y=>250);
my $tsl=$page2->Label(-text=>'Displays source file timestamps in the output log', -justify=>'left', -wraplength=>190) ->place(-x=>330, -y=>253); $tscb->select();
my $fpcb=$page2->Checkbutton(-text=>'/FP', -variable=>\$gGui{fpswitch}, -font=>"Adobe 10")->place(-x=>280, -y=>280);
my $fpl=$page2->Label(-text=>'Displays full pathnames of files in the output log', -justify=>'left', -wraplength=>190)->place (-x=>330, -y=>283); $fpcb->select();
my $wcb=$page2->Checkbutton(-text=>'/W', -variable=>\$gGui{wswitch}, -font=>"Adobe 10")->place(-x=>10, -y=>315);
$wcb->select();
my $wtf=$page2->Entry(-textvariable=>\$gGui{wentry}, -width=>8, -validate=> 'key',
-validatecommand=>sub{$_[0]=~ /^[0-9]?$/},
-invalidcommand=>sub{$page2->bell})->place(-x=>60, -y=>322);
my $wl=$page2->Label(-text=>'Specifies the wait time between entries -- 3-9 recommended', -justify=>'left', -wraplength=>160) ->place(-x=>120, -y=>313);
my $rcb=$page2->Checkbutton(-text=>'/R', -variable=>\$gGui{rswitch}, -font=>"Adobe 10")->place(-x=>280, -y=>315);
$rcb->select();
my $rtf=$page2->Entry(-textvariable=>\$gGui{rentry}, -width=>8, -validate=> 'key',
-validatecommand=>sub{$_[0]=~ /^[0-9]?$/},
-invalidcommand=>sub{$page2->bell})->place(-x=>325, -y=>322);
my $rl=$page2->Label(-text=>'Specifies the number of retries on failed copies -- 2-6 recommended', -justify=>'left', -wraplength=>160)->place(-x=>370, -y=>313);
my $clear2=$page2->Button(-text=>'CLEAR', -command=>\&clearsecond)->place(-x=>10, -y=>350);
my $back2=$page2->Button(-text=>'BACK', -command=>\&back_to_general_info)->place(-x=>70, -y=>350);
my $next2=$page2->Button(-text=>'NEXT', -command=>\&gotocollection, -foreground=>'blue', -activeforeground=>'blue')->place(-x=>480, -y=>350);
my $labell=$page2->Label(-text=>'Any combination of switches can be saved as defaults')->place(-x=>150, -y=>354);
#---------------------------------Third tab -- path and user-------------------------------------
my $page3=$notebook->add('page3', -label=>'Collection');
my $singlerb=$page3->Radiobutton(-text=>'Single Collection', -font=>"Adobe 12", -value=>1, -variable=>\$gGui{single}, -command=>\&single_collection)->place(-x=>90, -y=>2);
my $batchrb=$page3->Radiobutton(-text=>'Batch Collection', -font=>"Adobe 12", -value=>2, -variable=>\$gGui{batchb}, -command=>\&batch_collection)->place(-x=>300, -y=>2);
$batchrb->select();
my $filel=$page3->Label(-text=>'Names of files to act upon. You can use wildcard character ? and *', -foreground=>'red',-font=>"Times 12")->place(-x=>10, -y=>35);
my $filetf=$page3->Entry(-textvariable=>\$gGui{fileentry}, -width=>85)->place(-x=>10, -y=>60);
my $logfilenamel=$page3->Label(-text=>'RoboCopy Log File Name:', -state=>'disabled', -font=>"Times 12")->place(-x=>10, -y=>80);
my $logfilel = $page3 ->Label (-text=> '/LOG:file', -state=>'disabled', -foreground=>'red',-font=>"Times 12")->place (-x=> 10, -y=> 108);
my $logfiletf = $page3 ->Entry (-textvariable=>\$gGui{logname}, -state=>'disabled',-width=>27, -validate=>'key',
-validatecommand=>sub{$_[1]=~ /^[_ a-zA-Z0-9]?$/}, -invalidcommand=>sub{$page3->bell})->place (-x=> 80, -y=> 108);
my $logl=$page3->Label(-text=>'Log File(s) Path', -foreground=>'red',-font=>"Times 12")->place(-x=>10, -y=>138);
my $logpathb=$page3->Button(-text=>'[...]', -command=>\&log_dir_select, -foreground=>'blue', -activeforeground=>'blue')->place(-x=>230, -y=>138);
my $logtf=$page3->Label(-textvariable=>\$gGui{logpath}, -wraplength=>250, -justify=>'left')->place(-x=>10, -y=>163);
my $sourcel=$page3->Label(-text=>'Source Path', -foreground=>'red',-font=>"Times 12")->place(-x=>10, -y=>197);
my $sourcesizel=$page3->Label(-textvariable=>\$gGui{sourcesize},-foreground=>'blue')->place(-x=>168, -y=>200);
my $sourcecb=$page3->Checkbutton(-text=>'Total Size', -variable=>\$gGui{sourcesizecal})->place(-x=>93, -y=>200);
$sourcecb->select();
my $sourcedirb=$page3->Button(-text=>'[...]', -command=>\&source_dir_select, -foreground=>'blue', -activeforeground=>'blue')->place(-x=>230, -y=>197);
my $sourceentry=$page3->Label(-textvariable=>\$gGui{source}, -wraplength=>250, -justify=>'left')->place(-x=>10, -y=>222);
my $destl=$page3->Label(-text=>'Destination Path', -foreground=>'red',-font=>"Times 12")->place(-x=>10, -y=>272);
my $destsizel=$page3->Label(-textvariable=>\$gGui{destinationsize},-foreground=>'blue')->place(-x=>115, -y=>275);
my $destdirb=$page3->Button(-text=>'[...]', -command=>\&dest_dir_select, -foreground=>'blue', -activeforeground=>'blue')->place(-x=>230, -y=>272);
my $destentry=$page3->Label(-textvariable=>\$gGui{dest}, -wraplength=>250, -justify=>'left')->place(-x=>10, -y=>297);
my $table=$page3->Scrolled('HList',-columns=>2,-header=>1,-width=>28,-height=>10,-font=>"Times 12",-scrollbars=>'osoe')->place(-x=> 280, -y=> 115);
$table->placeForget();
my $change = $page3-> Button(-text=> 'MAKE CHANGES', -command=>\&changes)->place(-x=>460, -y=>355);
$change->placeForget();
my $sourcetextl=$page3->Label(-text=>'Directory comma name of log file. One per line (ex: clavel, Clare LaVel)', -wraplength=>225, -foreground=>'red',-font=>"Times 12", -justify=>'left')->place(-x=>285, -y=>85);
my $sourcetextentry=$page3->Scrolled('Text', -scrollbars=>'ose', -width=>32, -height=>13)->place(-x=>280, -y=>140);
my $okb=$page3->Button(-text=>' START ROBOCOPY ', -command=>\&confirmbatch, -foreground=>'blue', -activeforeground=>'blue')->place(-x=>320, -y=>350);
$okb->placeForget();
my $clear3=$page3->Button(-text=>'CLEAR', -command=>\&clearthird)->place(-x=>10, -y=>350);
my $back3=$page3->Button(-text=>'BACK', -command=>\&back_to_switches)->place(-x=>70, -y=>350);
my $progressta=$page3->Scrolled('Text', -scrollbars=>'se', -width=>65, -height=>20, -font=>"Times 12")->place(-x=>0, -y=>0);
$progressta->placeForget();
#---------------------------------OUTSIDE THE TAB-------------------------------------
my $quitb=$mw->Button(-text=>'QUIT', -command=>\&quit)->pack(-side=>'left');
my $starl=$mw->Label(-text=>'Required fields', -foreground=>'red')->place(-x=>70, -y=>449);
my $savedefaultb=$mw->Button(-text=>'SAVE DEFAULTS', -command=>\&savedef)->place(-x=>170, -y=>448);
my $loaddefaultb=$mw->Button(-text=>'LOAD DEFAULTS', -command=>\&loaddef)->place(-x=>270, -y=>448);
my $robob=$mw->Button(-text=>'START ROBOCOPY', -command=>\&roboc, -foreground=>'blue', -activeforeground=>'blue')->place(-x=>428, -y=>448);
MainLoop;
#------------------------------SUBROUTINES---------------------------------------
sub roboc{
$gGui{per}=0;
validate();
}#roboc
sub requirements{
if (eval "require 5.8.3" ){
}else {
my $require = $mw-> Dialog(
-title => 'Alert',
-text => "You need Active Perl version 5.8.3 or higher",
-buttons => [ qw(OK) ])->Show();
exit(0);
}#else
my $class = 'Win32::DirSize';
if (eval "require $class"){
} else {
my $module = $mw-> Dialog(
-title => 'Alert',
-text => "You need to install the Win32::DirSize module. Please refer to the user guide (under the HELP menu.)",
-buttons => [ qw(OK) ])->Show();
die;
}#else
my $class1 = 'Math::Round';
if (eval "require $class1"){
} else {
my $module = $mw-> Dialog(
-title => 'Alert',
-text => "You need to install the Math::Round module. Please refer to the user guide (under the HELP menu.)",
-buttons => [ qw(OK) ])->Show();
die;
}#else
my $class2 = 'File::Basename';
if (eval "require $class2"){
} else {
my $module = $mw-> Dialog(
-title => 'Alert',
-text => "You need to install the File::Basename module. Please refer to the user guide (under the HELP menu.)",
-buttons => [ qw(OK) ])->Show();
die;
}#else
my $binary = "robocopy.exe";
if (-e $binary){
} else {
my $module = $mw-> Dialog(
-title => 'Alert',
-text => "$binary not found. Please refer to the user guide (under the HELP menu.)",
-buttons => [ qw(OK) ])->Show();
die;
}#else
my $file1 = "RoboCopy.pdf";
my $file2 = "Guide.pdf";
if (-e $file1 || -e $file2){
} else {
my $robodoc = $mw-> Dialog(
-title => 'Alert',
-text => "The HELP tab will not work properly. Make sure $file1 and $file2 are in the folder where this application runs.",
-buttons => [ qw(OK) ])->Show();
}#else
}#sub requirements
sub quit{
my $answer = $mw-> Dialog(
-title => 'QUIT',
-text => "Are you sure you want to quit the program?",
-buttons => [ 'NO','YES' ],
-default_button => 'NO',
-bitmap => 'question')->Show();
if($answer eq 'YES'){
exit(0);
}#if
}#quit
sub robo{
my $file = "RoboCopy.pdf";
my @args = ("start",$file);
for (@args) {
if (/ /) { $_ = qq{"$_"};
}
};
system(@args) == 0
or warn "Couldn't launch '$file' : $!/$?/$^E";
}#robo
sub help{
my $file = "Guide.pdf";
my @args = ("start",$file);
for (@args) {
if (/ /) { $_ = qq{"$_"};
}
};
system(@args) == 0
or warn "Couldn't launch '$file' : $!/$?/$^E";
}#help
sub about{
my $about = $mw-> Dialog(
-title => 'ABOUT THIS PROGRAM',
-text => "FRIENDLYROBOCOPY\n
Version: 1.0\n
by Claire LaVelle\n
claire\@cleardigitalevidence.com")->Show();
}#about
sub gotoswitches{
$notebook->raise('page2');
}#gotoswitches
sub gotocollection{
$notebook->raise('page3');
}#gotocollection
sub back_to_general_info{
$notebook->raise('page1');
}#back_to_general_info
sub back_to_switches{
$notebook->raise('page2');
}#back_to_switches
sub log_dir_select{
$gGui{original_path}="\"";
my $a = $page3->chooseDirectory();
$gGui{logpath} = $a;
}#log_dir_select
sub source_dir_select{
$gGui{sourcesize}="";
$gGui{original_source}= "\"";
my $a = $page3->chooseDirectory();
$gGui{source} = $a;
if($gGui{single}==1){
$gGui{original_source} .= "$gGui{source}";
$gGui{source} =~s/\//\\/g;
if ($gGui{sourcesizecal}==1){
calsizeforsource();#calculates the size of the directory to copy
}#if
}#if
}#source_dir_select
sub dest_dir_select{
$gGui{original_dest}= "\"";
my $a = $page3->chooseDirectory();
$gGui{dest} = $a;
$gGui{original_dest} .= "$gGui{dest}";
$gGui{dest} =~s/\//\\/g;
calsizefordestination();#calculates the space available on the destination drive
}#dest_dir_select
sub comp_log_dir_select{
$gGui{complogpath}= "";
my $a = $page3->chooseDirectory();
$gGui{complogpath} = $a;
}#log_dir_select
sub save_switches{
my $a = "";#initialize
$a .= " $gGui{fileentry} /NP ";
if($gGui{lswitch}==1){$a .=" /L";}
if($gGui{sswitch}==1){$a .=" /S";}
if($gGui{eswitch}==1){$a .=" /E";}
if($gGui{xfswitch}==1 && $gGui{xfentry}){$a .=" /XF $gGui{xfentry}";}
if($gGui{xdswitch}==1 && $gGui{xdentry}){$a .=" /XD $gGui{xdentry}";}
if($gGui{wswitch}==1 && $gGui{wentry}) {$a .=" /W:$gGui{wentry}";}
if($gGui{rswitch}==1 && $gGui{rentry}){$a .=" /R:$gGui{rentry}";}
if($gGui{value}==3 && $gGui{copyentry}){$a .=" /COPY:$gGui{copyentry}";}
if($gGui{value}==1){$a .=" /COPYALL";}
if($gGui{value}==2){$a .=" /SEC";}
if($gGui{fpswitch}==1){$a .=" /FP ";}
if($gGui{tsswitch}==1){$a .=" /TS ";}
return ($a);
}#save_swiches
sub print_to_log{
open (LOG, ">$gGui{complogpath}/$gGui{complog}.txt");
print LOG ("-----------------------COMPREHENSIVE LOG FILE-------------------------\n
-------------------Created by FriendlyRoboCopy version 1.0--------------------\n
$date\n
Investigator's name: $gGui{investigator_name}\n
Investigator's Company: $gGui{investigator_co_name}\n
Investigator's company address: $gGui{investigator_co_add}\n
Investigator's company information: $gGui{investigator_co_phone}\n
Case number: $gGui{case_number}\n
Case name: $gGui{case_name}\n
Reason for investigation: $gGui{reason}\n
case address:\n
$gGui{case_info}\n");
if ($gGui{network_share} eq ""){
print LOG ("No Network share information.\n");
}else{
print LOG ("The network share info is: $gGui{network_share}\n");
}#else
if ($gGui{hard_drive} eq ""){
print LOG ("No hard drive information.\n");
}else{
print LOG ("The hard drive info is: $gGui{hard_drive}\n");
}#else
if ($gGui{system_serial} eq ""){
print LOG ("No system serial number.\n");
}else {
print LOG ("The system serial number is: $gGui{system_serial}\n");
}#else
if (length($gGui{message})==1){
print LOG ("No comments.\n");
}else{
print LOG ("The comments: $gGui{message}\n");
}#else
print LOG ("
The source path is: $gGui{source}\n
Size of the source directory: $gGui{sourcesize}\n
The destination path is: $gGui{dest}\n
Destination directory free space: $gGui{destinationsize}\n
The switches are: $gGui{switches}
\n");
if($gGui{single}==1){
print LOG ("The name of the log file is: $gGui{logname}
\n");
} else {
print LOG ("The user names are: \n$gGui{sourcetext}
\n");
}#else
print LOG ("The path for the log file is: $gGui{logpath}\n");
}#print_to_log
sub validate{
my $valone=2;
$valone = validate1($valone);
if($valone==1){
validate_two();
}else{
$notebook->raise('page1');
my $dialog = $page1-> Dialog(
-title => 'Alert',
-text => "Complete ALL Required Fields",
-buttons => [ qw(OK) ])->Show();
}#else
}#validate
sub validate_two{
my $valtwo=2;
$valtwo = validate2($valtwo);
if($valtwo==1 && $gGui{single}==1){#single collection case
create_file_for_single_three();
}elsif ($valtwo==1 && $gGui{single}==0){#batching collection case
continue_batching();
}else{
my $dialog = $page2-> Dialog(
-title => 'Alert',
-text => "Make sure the checkboxes are checked where textfields are filled",
-buttons => [ qw(OK) ])->Show();
}#else
}#create_file_for_single_two
sub create_file_for_single_three{
my $n = 0;
if($gGui{dest} && $gGui{source} && $gGui{logname} && $gGui{logpath} && $gGui{fileentry}){
$gGui{original_path} = "\"";
$gGui{original_path} .= "$gGui{logpath}\\";
$gGui{switches} = save_switches(); #calls the method save_switches
if ($gGui{sourcesizecal}==1){#was the check box to calculate source checked?
$gGui{per} = ($gGui{sbyte}* 100)/$gGui{dbyte};
if($gGui{per} > 97 || $gGui{sbyte}==0){
$n++;
my $dialog = $page3-> Dialog(
-title => 'Alert',
-text => "Destination too small or Source is 0.\n",
-buttons => [ qw(OK) ])->Show();
}#if
}#if
if ($n==0){
confirmsingle();
}#if
}else{
my $dialog = $page3-> Dialog(
-title => 'Alert',
-text => "Identify which files you want.\n
Enter a Destination, Source path and name the log file",
-buttons => [ qw(OK) ])->Show();
}#else
}#create_file_for_single_three
sub size{
}#size
sub continue_batching{
$gGui{sourcetext}="";
$gGui{sourcetext}=$sourcetextentry->get('1.0','end');#get the data from the text area
my $error=0;#numerical variable for error checking
my @line_array = split /\n/, $gGui{sourcetext}; #split by hard return
foreach my $line (@line_array){
if ($line !~ /\w+,\s\w+/){#makes sure that the format bbotta, Brent Botta is respected
$error++;#add one if the format is wrong
}#if
}#foreach
if($error==0 && ($gGui{dest}) && ($gGui{source}) && ($gGui{logpath}) && ($gGui{fileentry}) && (length($gGui{sourcetext})!=1)){#check if everything is ok
$table->place(-x=> 280,-y=> 120);
$gGui{original_source} .= "$gGui{source}";
$gGui{source} =~s/\//\\/g;
$gGui{original_path} = "\"";
$gGui{original_path} .= "$gGui{logpath}/";
$gGui{switches} = save_switches();
@arraybatch = split /,|\n/, $gGui{sourcetext}; #splits what is in the variable
for(my $i=1; $i<@arraybatch; $i=$i+2){ #makes an array for the full name
$arraybatch[$i] =~s/\G //g;#gets rid of the space in front
push @arrayfilename, $arraybatch[$i];
}#for
for(my $i=0; $i<@arraybatch; $i=$i+2){#makes an array for the user name
push @arraydirectory, $arraybatch[$i];
}#for
if($gGui{sourcesizecal}==1){
make_table();
} else {
make_table_one_column();
}#else
}else{
my $dialog = $page3-> Dialog(
-title => 'Alert',
-text => "Identify which files you want.\n
Enter the destination, source and log paths.\n
Fill out the textarea in this format: clavelle, Claire LaVelle.\n",
-buttons => [ qw(OK) ])
->Show();
}#else
}#continue_batching
sub make_table_one_column{
print "was here";
$gGui{sbyte}=0;
$table ->headerCreate(0, -text=>" Directory ");
foreach (@arraydirectory){
$table->add($_);
$table->itemCreate($_, 0, -text => $_);
}#for
$sourcetextl->placeForget();
$sourcetextentry->placeForget();
$sourcesizel->placeForget();
$robob->placeForget();
$destdirb->configure(-state=>'disabled');
$sourcedirb->configure(-state=>'disabled');
$sourcecb->configure(-state=>'disabled');
$logpathb->configure(-state=>'disabled');
$singlerb->configure(-state=>'disabled');
$batchrb->configure(-state=>'disabled');
$clear3->configure(-state=>'disabled');
$filetf->configure(-state=>'disabled');
$back3->configure(-state=>'disabled');
$notebook->pageconfigure('page2', -state=>'disabled');
$notebook->pageconfigure('page1', -state=>'disabled');
$okb->place(-x=>320, -y=>350);
$change->place(-x=>440, -y=>350);
$gGui{sourcesize}="";
}#make_table_one_column
sub make_table{
$gGui{sbyte}=0;
my $sourceSizeUnit;
$table ->headerCreate(0, -text=>" Directory ");
$table ->headerCreate(1, -text=>" Size ");
for (my $i=0; $i<@arraydirectory; $i++){
my $dir = $arraydirectory[$i];
my $cleansource = "$gGui{source}\\$dir";#append the \ to the user directory
my $sourceDirInfo;
my $sourceResult = dir_size($cleansource, $sourceDirInfo,);#get the size of the directory
$gGui{sbyte} += $sourceDirInfo->{DirSize}; #add the bytes of all of the directories
my $sourcebestsize = best_convert($sourceSizeUnit, $sourceDirInfo->{HighSize}, $sourceDirInfo->{LowSize},);
$sourcebestsize = nearest(.15, $sourcebestsize);
my $s = " $sourcebestsize $sourceSizeUnit";#append the size and the unit
$s .= "B";
$table->add("$dir/$i");
$table->itemCreate("$dir/$i", 0, -text => $dir);
$table->itemCreate("$dir/$i", 1, -text => $s);
}#for
$gGui{sbyteoriginal}=$gGui{sbyte};
my $totalsource = best_convert($sourceSizeUnit,int($gGui{sbyte}/2**32), $gGui{sbyte} % 2**32);
$totalsource = nearest(.15, $totalsource);
$gGui{sourcesize} = "( $totalsource $sourceSizeUnit";
$gGui{sourcesize} .= "B)";
$sourcesizel->place(-x=>168, -y=>200);
$sourcetextl->placeForget();
$sourcetextentry->placeForget();
$robob->placeForget();
$destdirb->configure(-state=>'disabled');
$sourcedirb->configure(-state=>'disabled');
$sourcecb->configure(-state=>'disabled');
$logpathb->configure(-state=>'disabled');
$singlerb->configure(-state=>'disabled');
$batchrb->configure(-state=>'disabled');
$clear3->configure(-state=>'disabled');
$filetf->configure(-state=>'disabled');
$back3->configure(-state=>'disabled');
$notebook->pageconfigure('page2', -state=>'disabled');
$notebook->pageconfigure('page1', -state=>'disabled');
$okb->place(-x=>320, -y=>350);
$change->place(-x=>440, -y=>350);
}#make_table
sub changes{
$back3->configure(-state=>'normal');
$notebook->pageconfigure('page2', -state=>'normal');
$notebook->pageconfigure('page1', -state=>'normal');
$clear3->configure(-state=>'normal');
$filetf->configure(-state=>'normal');
$batchrb->configure(-state=>'normal');
$singlerb->configure(-state=>'normal');
$destdirb->configure(-state=>'normal');
$sourcedirb->configure(-state=>'normal');
$sourcecb->configure(-state=>'normal');
$logpathb->configure(-state=>'normal');
$okb->placeForget();
$robob->place(-x=>428, -y=>448);
$sourcetextl->place(-x=>285, -y=>85);
$sourcetextentry->place(-x=>280, -y=>140);
$sourcetextentry->delete('1.0','end'); #clean the text area
splice @arraybatch, 0; #clean the array
foreach(my $i=0; $i<@arraydirectory; $i++){#put the information back in the text area
$sourcetextentry->insert('end lineend', $arraydirectory[$i]);
$sourcetextentry->insert('end lineend', ", ");
$sourcetextentry->insert('end lineend', $arrayfilename[$i]);
$sourcetextentry->insert('end lineend', "\n");
}#foreach
splice @arraydirectory, 0; #clean the directory array
splice @arrayfilename, 0; #clean the full name array
$table->delete('all'); #delete all the content of the table
$change->placeForget();
$table->placeForget();
$gGui{sourcetext}=""; #clean the variable that collects what is in the text area
$gGui{original_source} = "\"";
#$gGui{original_dest} = "\"";
$gGui{original_path} = "\"";
}#change
sub calsizefordestination(){
my $destDirInfo;
my $destSizeUnit;
my $destResult = disk_space($gGui{dest}, $destDirInfo,);
$gGui{dbyte} = $destDirInfo->{FreeBytes};
my $destSize = best_convert($destSizeUnit, $destDirInfo->{HighFreeBytes}, $destDirInfo->{LowFreeBytes},);
$destSize= nearest(.15, $destSize);
$gGui{destinationsize} = "( $destSize $destSizeUnit";
$gGui{destinationsize} .= "B)";
}#calsizefordestination
sub calsizeforsource(){
my $sourceDirInfo;
my $sourceSizeUnit;
my $sourceResult = dir_size($gGui{source}, $sourceDirInfo,);
$gGui{sbyte} = $sourceDirInfo->{DirSize};
my $sizesource = best_convert($sourceSizeUnit, $sourceDirInfo->{HighSize}, $sourceDirInfo->{LowSize},);
$sizesource = nearest(.15, $sizesource);
$gGui{sourcesize} = "( $sizesource $sourceSizeUnit";
$gGui{sourcesize} .= "B)";
}#calsizeforsource
sub confirmsingle(){
my $s = $gGui{original_source};
$s .= "\"";
my $d = $gGui{original_dest};
$d .= "\"";
my $l = $gGui{original_path};
chop $l;
$l .= "\"";
my $lp = "\"";
$lp .= "$gGui{complogpath}\"";
if ($gGui{sourcesizecal}==1){#was the check box to calculate source checked?
my $answer = $page3-> Dialog(
-title => 'ROBOCOPY OPERATION SUMMARY',
-wraplength => 550,
-text => "Source Ppath: $s\n
Source takes $gGui{per}% of destination\n
Destination path: $d\n
Robocopy log file path: $l\n
Robocopy log file name: $gGui{logname}\n
Comprehensive log file path: $lp\n
Comprehensive log file name: $gGui{complog}\n
Switches: $gGui{switches}\n",
-buttons => [ 'CANCEL','CONTINUE' ],
-default_button => 'CONTINUE')->Show();
if($answer eq 'CONTINUE'){
$gGui{original_source} .= "\"";
$gGui{original_dest} .= "\"";
$gGui{logname} .= ".log";
$gGui{switches} .= " /LOG:$gGui{original_path}$gGui{logname}\"";
$gGui{original_source} .= " $gGui{original_dest} $gGui{switches}";
print_to_log();
$notebook->pageconfigure('page3', -state=>'disabled');
$notebook->pageconfigure('page2', -state=>'disabled');
$notebook->pageconfigure('page1', -state=>'disabled');
$savedefaultb->placeForget();
$loaddefaultb->placeForget();
$robob->placeForget();
$progressta->place(-x=>0, -y=>0);
$progressta->insert('end lineend', "Robocopy is now processing $gGui{logname}\n");
system ("robocopy $gGui{original_source}");
first();
}#if
}else{
my $answer = $page3-> Dialog(
-title => 'ROBOCOPY OPERATION SUMMARY',
-wraplength => 550,
-text => "Source path: $s\n
The total of the source folders was not calculated.\n
No guarantee that RoboCopy can complete the job.\n
Destination path: $d\n
Robocopy log file path: $l\n
Robocopy log file name: $gGui{logname}\n
Comprehensive log file path: $lp\n
Comprehensive log file name: $gGui{complog}\n
Switches: $gGui{switches}\n",
-buttons => [ 'CANCEL','CONTINUE' ],
-default_button => 'CONTINUE')->Show();
if($answer eq 'CONTINUE'){
$gGui{original_source} .= "\"";
$gGui{original_dest} .= "\"";
$gGui{logname} .= ".log";
$gGui{switches} .= " /LOG:$gGui{original_path}$gGui{logname}\"";
$gGui{original_source} .= " $gGui{original_dest} $gGui{switches}";
print_to_log();
$notebook->pageconfigure('page3', -state=>'disabled');
$notebook->pageconfigure('page2', -state=>'disabled');
$notebook->pageconfigure('page1', -state=>'disabled');
$savedefaultb->placeForget();
$loaddefaultb->placeForget();
$robob->placeForget();
$progressta->place(-x=>0, -y=>0);
$progressta->insert('end lineend', "Robocopy is now processing $gGui{logname}\n");
system ("robocopy $gGui{original_source}");
first();
}#if
}#else
}#confirmsingle
sub confirmbatch{
my $s = $gGui{original_source};
$s .= "\"";
my $d = $gGui{original_dest};
$d .= "\"";
my $l = $gGui{original_path};
chop $l;
$l .= "\"";
my $lp = "\"";
$lp .= "$gGui{complogpath}\"";
if ($gGui{sourcesizecal}==1){#was the check box to calculate source checked?
$gGui{per} = ($gGui{sbyteoriginal}* 100)/$gGui{dbyte};#calculates the percent of the source in relation to the destination.
if($per > 97 || $gGui{sbyte}==0){
my $dialog = $page3-> Dialog(
-title => 'Alert',
-text => "Destination too small or Source has no data",
-buttons => [ qw(OK) ])->Show();
changes();
}else{
my $answerbatch = $page3-> Dialog(
-title => 'ROBOCOPY OPERATION SUMMARY',
-wraplength => 550,
-text => "Source path: $s\n
Source takes $gGui{per}% of destination\n
Destination Path: $d\n
Robocopy log file path: $l\n
Comprehensive log file path: $lp\n
Comprehensive log file name: $gGui{complog}\n
Switches: $gGui{switches}\n",
-buttons => [ 'CANCEL','CONTINUE' ],
-default_button => 'CONTINUE',
-bitmap => 'question')->Show();
if($answerbatch eq 'CONTINUE'){
$gGui{original_source} .= "/";
$gGui{original_dest} .= "\"";
$gGui{switches} .= " /LOG:$gGui{original_path}";
$gGui{original_dest} .= " $gGui{switches}";
print_to_log();#print to the log file
$notebook->pageconfigure('page3', -state=>'disabled');
$notebook->pageconfigure('page2', -state=>'disabled');
$notebook->pageconfigure('page1', -state=>'disabled');
$savedefaultb->placeForget();
$loaddefaultb->placeForget();
$robob->placeForget();
$progressta->place(-x=>0, -y=>0);
$progressta->update;
$progressta->after(10);
cont();
}#if
}#else
} else {
my $answerbatch = $page3-> Dialog(
-title => 'ROBOCOPY OPERATION SUMMARY',
-wraplength => 550,
-text => "Source path: $s\n
The total of the source folders was not calculated.\n
No guarantee that RoboCopy can complete the job.\n
Destination path: $d\n
Robocopy log file path: $l\n
Comprehensive log file Path: $lp\n
Comprehensive log file name: $gGui{complog}\n
Switches: $gGui{switches}\n",
-buttons => [ 'CANCEL','CONTINUE' ],
-default_button => 'CONTINUE',
-bitmap => 'question')->Show();
if($answerbatch eq 'CONTINUE'){
$gGui{original_source} .= "/";
$gGui{original_dest} .= "\"";
$gGui{switches} .= " /LOG:$gGui{original_path}";
$gGui{original_dest} .= " $gGui{switches}";
print_to_log();#print to the log file
$notebook->pageconfigure('page3', -state=>'disabled');
$notebook->pageconfigure('page2', -state=>'disabled');
$notebook->pageconfigure('page1', -state=>'disabled');
$savedefaultb->placeForget();
$loaddefaultb->placeForget();
$robob->placeForget();
$progressta->place(-x=>0, -y=>0);
$progressta->update;
$progressta->after(10);
cont();
}#if
}#else
}#confirmbatch
sub cont{
my $i=0;
foreach (@arrayfilename){
$_ .= ".log\"";
system ("robocopy $gGui{original_source}$arraydirectory[$i]\" $gGui{original_dest}$_");
chop $_;
$progressta->insert('end lineend', "Robocopy is now processing $_,\n");
$progressta->update;
$i++;
}#foreach
first();
}#cont
sub first{
if($gGui{single}==1){
error_report_single();
} else {
error_report_batch();
}#else
}#first
sub error_report_batch {
print LOG ("\n---------------------------------------ERROR REPORT------------------------------------\n");
foreach $user (@arrayfilename){
$file = "$gGui{logpath}/$user";#make the proper path before opening the log file
push @arrayfile, $file;
open (INPUT, "<$file")||die;
while(){
if(/ERROR 0/){
print LOG ("No errors occurred,and no copying was done. Examine the output log located at $file.\n");
}elsif(/ERROR 2/){
print LOG ("Some extra files or directories were detected. RoboCopy might have attempted to copy a folder that did not exist. Examine the output log located at $file.\n");
}elsif(/ERROR 4/){
print LOG ("Some mismatched files or directories were detected. Examine the output log located at $file. Still should have copied.\n");
}elsif(/ERROR 8/){
print LOG ("Some files or directories could not be copied (copy errors occured and the retry limit was exceeded). Investigate what happen if you have time and need a clean copy of ALL the data. The log file is located at $file\n");
}elsif(/ERROR 16/){
print LOG ("Serious error. Robocopy did not copy any files. This is either a usage error or an error due to insufficient access privileges on the source or destination directories. The log file is located at $file\n");
}elsif(/ERROR 32/){
print LOG ("Some files were not copied because they were in use by another process. Examine the output log located at $file.\n");
}#elsif
my @line = split ' ';
foreach my $line (@line){
push @array, $line;
}#foreach
}#while
}#foreach
my $i = 0;
my $j = 0;
for ($i=0; $i<@array; $i++){
if ($array[$i] eq "Skipped"){
if ($array[$i + 8]>0){
print LOG ("Robocopy skipped copying $array[$i + 8] directory(ies). For more info look at: $arrayfile[$j].\n");
}#if
if ($array[$i + 16]>0){
print LOG ("Robocopy skipped copying $array[$i + 16] file(s). For more info look at: $arrayfile[$j].\n");
}#if
if ($array[$i + 10]>0){
print LOG ("Robocopy FAILED to copy $array[$i + 10] directories. For more info look at: $arrayfile[$j].\n");
}#if
if ($array[$i + 18]>0){
print LOG ("Robocopy FAILED to copy $array[$i + 18] file(s). For more info look at: $arrayfile[$j].\n");
}#if
$j++;
}#if
}#for
close LOG;
lastsub();
}#error_report_batch
sub error_report_single{
print LOG ("\n------------------------------ERROR REPORT-------------------------------\n");
open (INPUT, "<$gGui{logpath}/$gGui{logname}")||die;
while(){
if(/ERROR 2/){
print LOG ("Some extra files or directories were detected. Examine the output log.\n");
}elsif(/ERROR 4/){
print LOG ("Some mismatched files or directories were detected. Examine the output log. Still should have copied.\n");
}elsif(/ERROR 8/){
print LOG ("Some files or directories could not be copied (copy errors occured and the retry limit was exceeded). Investigate what happen if you have time and need a clean copy of ALL the data.\n");
}elsif(/ERROR 16/){
print LOG ("Serious error. Robocopy did not copy any files. This is either a usage error or an error due to insufficient access privileges on the source or destination directories.\n");
}elsif(/ERROR 32/){
print LOG ("Some files were not copied because they were in use by another process.\n");
}#elsif
my @line = split ' ';
foreach my $line (@line){
push @array, $line;
}#foreach
}#while
my $i = 0;
for ($i=0; $i<@array; $i++){
if ($array[$i] eq "Skipped" ){
if ($array[$i + 8]>0){
print LOG ("Robocopy skipped copying $array[$i + 8] directory(ies).\n");
}#if
if ($array[$i + 16]>0){
print LOG ("Robocopy skipped copying $array[$i + 16] file(s).\n");
}#if
if ($array[$i + 10]>0){
print LOG ("Robocopy FAILED to copy $array[$i + 10] directories.\n");
}#if
if ($array[$i + 18]>0){
print LOG ("Robocopy FAILED to copy $array[$i + 18] file(s).\n");
}#if
}#if
}#for
close LOG;
lastsub();
}#error_report_single method
sub lastsub{
my $dialog = $page3-> Dialog(
-title => 'REPORT',
-text => "Open the Comprehensive Log File?",
-buttons => [ 'NO', 'YES'],
-default_button => 'YES', -bitmap => 'question')->Show();
if ($dialog eq "YES"){
logfile();
}#if
my $dialog1 = $page3-> Dialog(
-title => 'START OVER',
-text => "Continue using FriendlyRoboCopy?",
-buttons => [ 'NO', 'YES'],
-default_button => 'YES', -bitmap => 'question')->Show();
if ($dialog1 eq "YES"){
start_over();
} else {exit(0);}#else
}#lastsub
sub logfile{
my @args = ("start/d","$gGui{complogpath}/$gGui{complog}.txt");
my $file = pop(@args);
push (@args, '"'. dirname($file) . '"', basename($file));
system(@args) == 0
or warn "Couldn't launch '$file' : $!/$?/$^E";
}#logfile
sub batch_collection{
$okb->placeForget();
$batchrb->select();
$singlerb->deselect();
$sourcetextentry->place(-x=>280, -y=>140);#makes the textarea show up -- in case the table is up
$sourcetextl->place(-x=>285, -y=>85);#makes the label that goes with the textarea -- in case the table is up
$sourcetextentry->configure(-state=>'normal');#makes the textarea available for entry
$sourcetextl->configure(-state=>'normal');#makes the label looks alive
#$calculate_sizeb->placeForget();#disable the continue button for the single collection
#$calculate_and_create_fileb->place(-x=>460, -y=>350);#makes the continue button for batch able
$logfiletf->configure(-state=>'disabled');#makes the log file name unable
$logfilel->configure(-state=>'disabled');#makes the label for the log file name look dead
$logfilenamel->configure(-state=>'disabled'); #makes the lable for the name of the robocopy log file unable
$gGui{logname}="";#clean what is in the log name variable
#$gGui{logpath}="";#clean the path variable
$gGui{sourcesize}="";#clean the source size variable
$gGui{source}="";#clean the variable that shows in the textfield for source
}#batch_collection
sub single_collection{
$gGui{sourcesize}="";
$gGui{source}="";
$table->delete('all');
$table->placeForget();
$change->placeForget();
$okb->placeForget();
#$calculate_sizeb->place(-x=>460, -y=>350);
$logfiletf->configure(-state=>'normal');
$logfilel->configure(-state=>'normal');
$logfilenamel->configure(-state=>'normal');
#$calculate_and_create_fileb->placeForget();
$sourcetextentry->place(-x=>280, -y=>140);
$sourcetextentry->delete('1.0','end');
$gGui{sourcetext}="";
$sourcetextl->place(-x=>285, -y=>85);
$sourcetextentry->configure(-state=>'disabled');
$sourcetextl->configure(-state=>'disabled');
$batchrb->deselect();
$singlerb->select();
}#single_collection
sub validate1{
my $value = @_;
$gGui{message} = $messagetf->get('1.0','end');
if($gGui{investigator_name} && $gGui{investigator_co_name} &&
$gGui{investigator_co_add} &&
$gGui{investigator_co_phone} &&
$gGui{case_number} &&
$gGui{reason} &&
$gGui{case_name} && $gGui{case_info} &&
$gGui{complogpath} && $gGui{complog}){
$notebook->raise('page3');
$value = 1;
return $value;
}else{
$value = 0;
return $value;
}#else
}#validate1
sub validate2{
my $value = @_;
if(($gGui{xfswitch}==1 && $gGui{xfentry} eq "" || $gGui{xfswitch}==0 && $gGui{xfentry}) ||
($gGui{xdswitch}==1 && $gGui{xdentry} eq "" || $gGui{xdswitch}==0 && $gGui{xdentry}) ||
($gGui{wswitch}==1 && $gGui{wentry} eq "" || $gGui{wswitch}==0 && $gGui{wentry}) ||
($gGui{rswitch}==1 && $gGui{rentry} eq "" || $gGui{rswitch}==0 && $gGui{rentry}) ||
($gGui{value}==3 && $gGui{copyentry} eq "")){
$notebook->raise('page2');
$value = 0;
return $value;
}else{
$notebook->raise('page3');
$value = 1;
return $value;
}#else
}#validate2
sub savedef(){
my $alert = $mw-> Dialog(
-title => 'Alert',
-text => "This will erase the previous defaults",
-buttons => [ 'CANCEL','SAVE' ],
-default_button => 'SAVE')->Show();
if($alert eq 'SAVE'){
open(DEFAULTOUT, ">default.txt");
print DEFAULTOUT ("$gGui{investigator_name}:$gGui{investigator_co_name}:$gGui{investigator_co_add}:$gGui{investigator_co_phone}:$gGui{lswitch}:$gGui{eswitch}:$gGui{sswitch}:$gGui{value}:$gGui{xfswitch}:$gGui{xfentry}:$gGui{xdswitch}:$gGui{xdentry}:$gGui{wswitch}:$gGui{wentry}:$gGui{rswitch}:$gGui{rentry}:$gGui{tsswitch}:$gGui{fpswitch}:$gGui{copyentry}:$gGui{fileentry}:");
close DEFAULTOUT;
}#if
}#savedef
sub nofile(){
my $alert = $mw-> Dialog(
-title => 'Alert',
-text => "No defaults to load. Save defaults first",
-buttons => [ 'OK' ])->Show();
}#nofile
sub loaddef{
my @arraydefault;
open (DEFAULTIN, "){
chomp;
@arraydefault = split /:/; #put each element in an array
}#while
$gGui{investigator_name}=$arraydefault[0];
if ($gGui{investigator_name} eq ""){ $gGui{investigator_name}="";}
$gGui{investigator_co_name} = $arraydefault[1];
if ($gGui{investigator_co_name} eq ""){ $gGui{investigator_co_name}="";}
$gGui{investigator_co_add} = $arraydefault[2];
if ($gGui{investigator_co_add} eq ""){ $gGui{investigator_co_add}="";}
$gGui{investigator_co_phone} = $arraydefault[3];
if ($gGui{investigator_co_phone} eq ""){ $gGui{investigator_co_phone}="";}
$gGui{lswitch}=$arraydefault[4];
if ($gGui{lswitch}==1){ $lcb->select();} else {$lcb->deselect();}
$gGui{eswitch}=$arraydefault[5];
if ($gGui{eswitch}==1){ $ecb->select();} else {$ecb->deselect();}
$gGui{sswitch}=$arraydefault[6];
if ($gGui{sswitch}==1){ $scb->select();} else {$scb->deselect();}
$gGui{value}=$arraydefault[7];
if ($gGui{value}==2){$seccb->select();
} elsif ($gGui{value}==3){$copycb->select();
} else {$copyallcb->select();}#else
$gGui{xfswitch}=$arraydefault[8];
if ($gGui{xfswitch}==1){ $xfcb->select();} else {$xfcb->deselect();}
$gGui{xfentry}=$arraydefault[9];
if ($gGui{xfentry} eq ""){ $gGui{xfentry}="";}
$gGui{xdswitch}=$arraydefault[10];
if ($gGui{xdswitch}==1){ $xdcb->select();} else {$xdcb->deselect();}
$gGui{xdentry}=$arraydefault[11];
if ($gGui{xdentry} eq ""){ $gGui{xdentry}="";}
$gGui{wswitch}=$arraydefault[12];
if ($gGui{wswitch}==1){ $wcb->select();} else {$wcb->deselect();}
$gGui{wentry}=$arraydefault[13];
if ($gGui{wentry} eq ""){ $gGui{wentry}="";}
$gGui{rswitch}=$arraydefault[14];
if ($gGui{rswitch}==1){ $rcb->select();} else {$rcb->deselect();}
$gGui{rentry}=$arraydefault[15];
if ($gGui{rentry} eq ""){ $gGui{rentry}="";}
$gGui{tsswitch}=$arraydefault[16];
if ($gGui{tsswitch}==1){ $tscb->select();} else {$tscb->deselect();}
$gGui{fpswitch}=$arraydefault[17];
if ($gGui{fpswitch}==1){ $fpcb->select();} else {$fpcb->deselect();}
$gGui{copyentry}=$arraydefault[18];
if ($gGui{copyentry} eq ""){ $gGui{copyentry}="";}
$gGui{fileentry}=$arraydefault[19];
if ($gGui{fileentry} eq ""){ $gGui{fileentry}="";}
close DEFAULTIN;
}#loaddef
sub start_over{
$progressta->delete('1.0','end');
$progressta->placeForget();
$savedefaultb->place(-x=>170, -y=>448);
$loaddefaultb->place(-x=>270, -y=>448);
$robob->place(-x=>428, -y=>448);
$notebook->pageconfigure('page3', -state=>'normal');
$notebook->pageconfigure('page2', -state=>'normal');
$notebook->pageconfigure('page1', -state=>'normal');
$notebook->raise('page1');
clearfirst();
clearsecond();
clearthird();
}#start_over
sub clearfirst{
$gGui{investigator_name}="";
$gGui{investigator_co_name}="";
$gGui{investigator_co_add}="";
$gGui{investigator_co_phone}="";
$gGui{case_number}="";
$gGui{case_name}="";
$gGui{reason}="";
$gGui{case_info}="";
$gGui{network_share}="";
$gGui{hard_drive}="";
$gGui{system_serial}="";
$messagetf->delete('1.0','end');
$gGui{complogpath} ="";
$gGui{complog}="";
}#clearfrist
sub clearsecond{
$gGui{lswitch}=0;
$gGui{sswitch}=0;
$gGui{eswitch}=0;
$gGui{value}=1;
$gGui{copyentry}="";
#$copytf->delete(0,'end');
$gGui{xfswitch}=0;
$gGui{xfentry}="";
$gGui{xdswitch}=0;
$gGui{xdentry}="";
$gGui{wswitch}=1;
$gGui{wentry}=3;
$gGui{rswitch}=1;
$gGui{rentry}=3;
$gGui{tsswitch}=1;
$gGui{fpswitch}=1;
}#clearsecond
sub clearthird(){
$gGui{original_source}="";
$gGui{original_dest}="";
$gGui{original_path}="";
$gGui{fileentry}="*.*";
$batchrb->configure(-state=>'normal');
$singlerb->configure(-state=>'normal');
splice @arraybatch, 0;
splice @arraydirectory, 0;
splice @arrayfilename, 0;
$destdirb->configure(-state=>'normal');
$sourcedirb->configure(-state=>'normal');
$logpathb->configure(-state=>'normal');
$okb->placeForget();
$gGui{logname}="";
$table->delete('all');
$table->placeForget();
$change->placeForget();
$sourcetextentry->place(-x=>280, -y=>140);
$sourcecb->place(-x=>95, -y=>200);
$sourcecb->select();
$sourcetextl->place(-x=>285, -y=>85);
# $calculate_sizeb->placeForget();
#$calculate_and_create_fileb->place(-x=>460, -y=>350);
$sourcetextentry->configure(-state=>'normal');
$sourcetextentry->delete('1.0','end');
$sourcetextl->configure(-state=>'normal');
$logfiletf->configure(-state=>'disabled');
$logfilel->configure(-state=>'disabled');
$logfilenamel->configure(-state=>'disabled');
$gGui{logpath}="";
$batchrb->select();
$singlerb->deselect();
$gGui{source}="";
$gGui{dest}="";
$gGui{destinationsize}="";
$gGui{sourcesize}="";
$gGui{sourcetext}="";
$filetf->configure(-state=>'normal');
$clear3->configure(-state=>'normal');
}#clearthird