http://qs321.pair.com?node_id=299572

nsyed has asked for the wisdom of the Perl Monks concerning the following question:

Hello, fellow monks. I am still a learning monk so for give me for asking a very basic question. There are 2 parts of my code. First is to FTP a file from one server to another which works. Then compare the sizes of two files that is the source file and destination file. My file compare part of the code works only on the local files but on the network files I get file not found erroe. Please help. Thank you in advance.
############# FTP code that works #!/usr/bin/perl use strict; use File::stat qw(:FIELDS); use Net::FTP; my $s_user = "user1"; my $d_user = "user2"; my $s_passwd = my $d_passwd ="mypassword"; my $s_host = "some-server.com"; my $d_host = "some-server.com"; my $s_file = my $d_file = "test.txt"; my $s_ftp = Net::FTP->new($s_host) or die "$@"; my $d_ftp = Net::FTP->new($d_host) or die "$@"; $s_ftp->login($s_user, $s_passwd) or die $s_ftp->message; $d_ftp->login($d_user, $d_passwd) or die $d_ftp->message; my $s_dir = "/home/test/source"; my $d_dir = "/home/test/dest"; $s_ftp->cwd($s_dir) or die "Can't cwd to $s_dir\n"; $d_ftp->cwd($d_dir) or die "Can't cwd to $d_dir\n"; $s_ftp->binary() or die $s_ftp->message; $d_ftp->binary() or die $s_ftp->message; $s_ftp->pasv_xfer($s_file, $d_ftp, $d_file) or warn $s_ftp->ok ? $d_ftp->message : $s_ftp->message; $d_file = $s_file unless length $d_file; ##This will compare the size of two files and is not working $stat = stat($s_file) or die "Can't open File :$!"; if ($st_size & $st_mtime) { $size1 = $st_size; $mtime1 = $st_mtime; } $stat = stat($d_file) or die "Can't open File opened :$!"; if ($st_size & $st_mtime) { $size2 = $st_size; $mtime2 = $st_mtime; } if ($size1 == $size2) { print "File size matches.\n"; print ("Sourfile and Destination File sizes are :", $size1 ," ", $size2 , "\n"); }else{ print "Source file and Destination file have different sizes!\n"; print ("Sourfile and estination File sizes are :", $size1 ," ", $size2 , "\n"); } $s_ftp->quit; $d_ftp->quit;

Replies are listed 'Best First'.
Re: comparing files after FTP
by demerphq (Chancellor) on Oct 15, 2003 at 23:41 UTC

    Id just like to point out that this is some scary code. Duplication like you have in that first section just screams out "refactor me!" You should convert as much of that into a subroutine, and then call it twice with the appropriate values. A perfect example of why you should do this are the following two lines

    $s_ftp->binary() or die $s_ftp->message; $d_ftp->binary() or die $s_ftp->message;

    while you were cutting an pasting you forgot to change the second error condition from $s_ftp to $d_ftp. If I were writing it the code would probably look something like this:

    use strict; use warnings; use Carp; sub die_msg { my $ftp=shift; Carp::confess join "",@_,":\n",$ftp->message; } sub do_connect { my ($user,$pass,$host,$dir)=@_; my $ftp=Net::FTP->new($host) or die "Failed to connect to host '$host':$@"; $ftp->login($user,$pass) or die_msg $ftp,"Failed login"; $ftp->binary() or die_msg $ftp,"Failed to switch to binary mode"; $ftp->cwd($dir) or die "Cant cwd '$dir'"; return $ftp; } my $source_ftp=do_connect('user1','mypassword','some-server.com','/hom +e/test/source'); my $dest_ftp =do_connect('user2','mypassword','some-server.com','/hom +e/test/dest'); my $source_file = "test.txt"; my $dest_file ||= $source_file; $source_ftp->pasv_xfer($source_file, $dest_ftp, $dest_file) or warn "Failed xfer:\n" . $source_ftp->ok ? $dest_ftp->message : $source_ftp->message;

    (Yes I know this doesnt address your real question. But this is also good advice. :-)

    ---
    demerphq

      First they ignore you, then they laugh at you, then they fight you, then you win.
      -- Gandhi


      Thanks a lot for the advice "demerphq" . As I mentioned I am still a newbie. I know I could have writen a better code. But I just wanted to keep it simple. Thank you all. I will try your recomendations and post the complete solution. Thanks
Re: comparing files after FTP
by vek (Prior) on Oct 15, 2003 at 23:16 UTC

    If you want to get the filesize on the remote server then use the size method.

    my $remote_size = $ftp->size($the_file);
    -- vek --
      Hi Vek, Its returning the size 0. Any more suggestions? Thanks

        Take a peek at File::Listing's parse_dir function. You should be able to grab the file size by using that. Untested:

        use File::Listing qw(parse_dir); # your ftp code here. my @dirlist = $ftp->ls("-l"); for (parse_dir(@dirlist)) { ($name, $type, $size, $mtime, $mode) = @$_; next if $type ne 'f'; # only want plain files print "Size of $name is $size\n"; }
        -- vek --
        I tried to make it simple but still doesn't work. It returns nothing. Please let me know if you can find anything wrong with this code or modify to get the size of the remote file. Thanks
        #!/usr/bin/perl use strict; use Net::FTP; my $user = "someuser"; my $passwd ="password";; my $host = "someFTPserver.com"; my $file = "somefile.txt"; my $ftp = Net::FTP->new($host) or die "$@"; $ftp->login($user, $passwd) or die $ftp->message; my $dir = "/home/somedir/mydir/dest"; $ftp->cwd($dir) or die "Can't cwd to $dir\n"; my $remote_size = $ftp-> size($file); print ("The source file size is :", $remote_size , "\n"); $ftp->quit;
Re: comparing files after FTP
by mandog (Curate) on Oct 15, 2003 at 22:38 UTC

    stat only works on a file sytem mounted on the machine you are running from. You might be able to do something with:

     my @itemes=Net::FTP->dir();

    (Sorry I don't have an ftp server to play with)

    update: do like vek says and use the size method.