Win32-Backup-Robocopy

 view release on metacpan or  search on metacpan

lib/Win32/Backup/Robocopy.pm  view on Meta::CPAN

		4   =>  'Some Mismatched files or directories were detected. '.
				'Examine the output log. Housekeeping might be required.',
		8   =>  'Some files or directories could not be copied '.
				'(copy errors occurred and the retry limit was exceeded). '.
				'Check these errors further.',
		16  =>  'Serious error. Robocopy did not copy any files. '.
				'Either a usage error or an error due to insufficient access privileges '.
				'on the source or destination directories.'
	);
	my $exitstr = '';
	foreach my $code(sort {$a<=>$b} keys %exit_code){
		if ( $exit == 0){
			$exitstr .= $exit_code{0};
			last;
		}
		$exitstr .= ' '.$exit_code{$code} if ($exit & $code);
	}
	return $exitstr;	
}
sub _validrange {
	my $range = shift;
	$range =~ s/\s//g;
	my @range;
	# allowed only . , \d \s
	croak 'invalid range ['.$range.'] (allowed only [\s.,\d])!' if $range =~ /[^\s,.\d]/;
	# not allowed a lone .
	croak 'invalid range ['.$range.'] (single .)!' if $range =~ /(?<!\.)\.(?!\.)/;
	# not allowed more than 2 .
	croak 'invalid range ['.$range.'] (more than 2 .)!' if $range =~ /\.{3}/;
	# $1 > $2 like in 25..7
	 if ($range =~ /[^.]\.\.[^.]/){
		foreach my $match ( $range=~/(\d+\.\.\d+)/g ){
			$match=~/(\d+)\.\.(\d+)/;
			croak "$1 > $2 in range [$range]" if $1 > $2;
		}
	}
	@range = eval ($range);
	my %single = map{ $_ => 1} @range;
	@range = sort{ $a <=> $b } keys %single;
	#print "RANGE:@range\n";
	return @range;
}
sub _waitdrive{
	my $self = shift;
	my $drive = shift;
	print 	"\nBackup of:     $self->{src}\n".
			"To:              $self->{dst}\n".
			"Waiting for drive $drive to be available..\n".
			"(press ENTER when $drive is connected or CTRL-C to terminate the program)\n";
	my $input = <STDIN>;
	$self->run();
}
sub _load_conf{ 
	my $file = shift;
	return [] unless -e -r -f $file;
	# READ the configuration 
	my $json = JSON::PP->new->utf8->pretty->canonical;
	open my $fh, '<', $file or croak "unable to read $file";
	my $lines;
	{
		local $/ = '';
		$lines = <$fh>;
	}
	close $fh or croak "impossible to close $file";
	my $data;
	{ 
		local $@;
		eval { $data = $json->decode( $lines ) };
		croak "malformed json in $file!\nJSON error:\n[$@]\n" if $@;
	}
	croak "not an ARRAY ref retrieved from $file as conteainer for jobs! wrong configuration" 
			unless ref $data eq 'ARRAY';
	my @check = qw( name src dst files history cron next_time next_time_descr first_time_run archive
				archiveremove subfolders emptysubfolders verbose waitdrive wait retries);
	my $count = 1;
	foreach my $job ( @$data ){
		croak "not a HASH ref retrieved from $file for job $count! wrong configuration" 
			unless ref $job eq 'HASH';
		map { 
				croak "field [$_] not present in the job $count retrieved from $file" 
				unless exists $job->{ $_ } 
		} @check;
		carp "unexpected elements in job $count  retrieved from $file" if keys %$job > @check;
		$count++;
	}
	return $data;
}
sub _write_conf{
	my $self = shift;
	my $json = JSON::PP->new->utf8->pretty->canonical;
	$json->sort_by( \&_ordered_json );
	# verbosity
	if ( $self->{ verbose } and -e $self->{ conf } ){
		print "overwriting configuration file $self->{ conf }\n";
	}
	open my $fh, '>', $self->{ conf } 
			or croak "unable to write configuration to [$self->{ conf }]";
	print $fh $json->encode( $self->{ jobs } );
	close $fh or croak "unable to close configuration file [$self->{ conf }]";
	# verbosity
	if ( $self->{verbose} > 2 ){
		print "resulting configuration:\n";
		print $json->encode(  $self->{ jobs } );
	}
	# verbosity
	print "wrote configuration file $self->{ conf }\n" if $self->{ verbose };
}
sub _get_cron{
	my $crontab = shift;
	my $cron;
	# a safe scope for $@ 
	{  
		local $@;
		eval { 
				$cron = Algorithm::Cron->new(
												base => 'local',
												crontab => $crontab 
											)
		} or croak "specify a valid cron entry as cron parameter!\n".
					"\tAlgorithm::Cron error is: $@";			
	} 



( run in 0.756 second using v1.01-cache-2.11-cpan-8dfa8b56332 )