#!/usr/bin/perl -w
use strict;
use warnings;
use Net::SFTP;
use Net::SFTP::Attributes;
unless( @ARGV == 5) {
print <<END;
Proper Usage:
perl sync local_path remote path user pass
END
exit(0);
}
my($local_path, $host, $remote_path, $user, $pass) = @ARGV;
my(%args) = ( 'user' => $user,
'password' => $pass
);
my $sftp = Net::SFTP->new($host, %args) or die "pasta\n";
die "SFTP Connection Failed\n" if $sftp->status;
#read_local_dir("$local_path/");
#print "----\n";
#$sftp->ls("/");
#read_remote_dir($sftp,"$remote_path/");
sync($sftp, $local_path, $remote_path, "");
sub sync {
my $sftp = shift;
my $local = shift;
my $remote = shift;
my $path = shift;
my( $loc_file, $loc_dir) = read_local_dir("$local/$path");
my( $rem_file, $rem_dir) = read_remote_dir($sftp, "$remote/$path");
while( my($lk,$lv) = each %$loc_file ) {
my $flag = 0;
while( my($rk,$rv) = each %$rem_file ) {
if($lk eq $rk) {
if($lv > $rv) {
# put $lk
$sftp->put("$local/$path/$lk","$remote/$path/$lk");
} elsif($lv < $rv) {
# get $rk
$sftp->get("$remote/$path/$lk", "$local/$path/$lk");
}
$flag = 1;
}
}
if( $flag == 0 ) {
# put $lk
$sftp->put("$local/$path/$lk","$remote/$path/$lk");
}
}
while( my($rk,$rv) = each %$rem_file ) {
my $flag = 0;
while( my($lk,$lv) = each %$loc_file ) {
if( $lk eq $rk ) {
$flag = 1;
}
}
if( $flag == 0 ) {
# get $rk
$sftp->get("$remote/$path/$rk", "$local/$path/$rk");
}
}
while( my($lk,$lv) = each %$loc_dir ) {
my $flag = 0;
next if $lk =~ /^\./;
while( my($rk,$rv) = each %$rem_dir ) {
if( $lk eq $rk ) {
sync( $sftp, $local, $remote, "$path/$lk");
$flag = 1;
}
}
if( $flag == 0 ) {
# create dir
my $att = Net::SFTP::Attributes->new(Stat => [stat "$local/$path/
+$lk"]);
$sftp->do_mkdir( "$remote/$path/$lk" , $att);
# sync it
sync( $sftp, $local, $remote, "$path/$lk" );
}
}
while( my($rk,$rv) = each %$rem_dir ) {
my $flag = 0;
next if $rk =~ /^\./;
while( my($lk,$lv) = each %$loc_dir ) {
if( $lk eq $rk ) {
$flag = 1;
}
}
if( $flag == 0 ) {
# create dir
mkdir("$local/$path/$rk");
# sync it
sync( $sftp, $local, $remote, "$path/$rk" );
}
}
}
sub read_local_dir {
my $path = shift;
my $file = {};
my $dir = {};
my $f;
opendir DIR, $path or
die "Failed to open $path: $!\n";
while($f = readdir DIR) {
my(@stats) = stat "$path/$f";
if(-d "$path/$f"){
$dir->{$f} = $stats[9];
} else {
$file->{$f} = $stats[9];
}
}
return ($file, $dir);
}
sub read_remote_dir {
my $sftp = shift;
my $path = shift;
my $file = {};
my $dir = {};
$sftp->ls( $path , sub {
my $ref = shift;
if( $ref->{'longname'} =~ /^d/ ) {
$dir->{$ref->{'filename'}} =$ref->{'a'}->mtime();
} else {
$file->{$ref->{'filename'}} =$ref->{'a'}->mtime();
}
});
return ($file, $dir);
}
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.