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

Hello all, I am writing a program that has a subroutine to do an FTP put to a server. My problem is I am looking for a way to determine if the FTP was sucessful or not, if not give as much info on the error as possible and pass that info back to my program regardless of success or failure.
sub PutFTP { ################################################################## +######################## # # This subroutine performs an FTP Put using the Net::FTP module # ################################################################## +######################## my $ftp_server = shift(@_); my $sub_pass = shift(@_); my $sub_uid = 'weblog'; my $sub_path = shift(@_); my $sub_log = shift(@_); print "Beginning FTP Put to $ftp_server. Putting log $sub_log to p +ath $sub_path\n\n"; print "FTP Debug output:\n\n"; my $ftp = Net::FTP->new("$ftp_server", Debug => 1, Timeout => 1300 +) or ErrorOut("Cannot connect to $ftp_server: $@"); $ftp->login($sub_uid,$sub_pass) or ErrorOut("Cannot login ", $ftp->message); $ftp->cwd($sub_path) or ErrorOut("Cannot change working directory ", $ftp->message); $ftp->put($sub_log) or ErrorOut("put failed ", $ftp->message); $ftp->quit; print "\nEnd FTP debug output\n\n"; if ($ftp->put($sub_log)) { print "FTP Put successful from server $ftp_server\n"; }else{ print "FTP Put Failed\n"; } } # End sub NetFTP
Every time it runs it says the put failed. Thanks in advance, Nick

Replies are listed 'Best First'.
Re: Error Checking with Net::FTP
by starX (Chaplain) on Jan 07, 2008 at 19:11 UTC
    If I'm not mistaken, the second check is redundant. You're successfully doing $ftp-put($sub_log), and then trying to do it a second time with the line if($ftp->put($sub_log)) {, which fails because it's trying to put a file that already exists. Try the last block as:
    $ftp->put($sub_log) or ErrorOut("FTP Put Failed ", $ftp->message); $ftp->quit; print "\nEnd FTP debug output\n\n"; print "FTP Put successful from server $ftp_server\n";
    If there's a problem, ErrorOut() should be able to report/handle it.
      Thanks for the quick replies! Actually the FTP is working fine. What I need is a way to determine after the get/put if it was sucessful. A sample of my output may clear it up:
      FTP Debug output: Net::FTP=GLOB(0x4041cfd8)<<< 220 server FTP server ready. Net::FTP=GLOB(0x4041cfd8)>>> USER weblogs Net::FTP=GLOB(0x4041cfd8)<<< 331 Password required for weblogs. Net::FTP=GLOB(0x4041cfd8)>>> PASS .... Net::FTP=GLOB(0x4041cfd8)<<< 230 User weblogs logged in. Net::FTP=GLOB(0x4041cfd8)>>> CWD /export/home/weblogs/subsidiary/ Net::FTP=GLOB(0x4041cfd8)<<< 250 CWD command successful. Net::FTP=GLOB(0x4041cfd8)>>> PORT 170,6,240,108,208,249 Net::FTP=GLOB(0x4041cfd8)<<< 200 PORT command successful. Net::FTP=GLOB(0x4041cfd8)>>> RETR subsidiary.28067.access.file.log Net::FTP=GLOB(0x4041cfd8)<<< 150 Opening ASCII mode data connection fo +r subsidiary.28067.access.file.log (40641 bytes). Net::FTP=GLOB(0x4041cfd8)<<< 226 Transfer complete. Net::FTP=GLOB(0x4041cfd8)>>> QUIT Net::FTP=GLOB(0x4041cfd8)<<< 221-You have transferred 40841 bytes in 1 + files. Net::FTP=GLOB(0x4041cfd8)<<< 221-Total traffic for this session was 41 +290 bytes in 1 transfers. Net::FTP=GLOB(0x4041cfd8)<<< 221-Thank you for using the FTP service o +n server. Net::FTP=GLOB(0x4041cfd8)<<< 221 Goodbye. End FTP debug output FTP Get Failed
      See the FTP debug shows the get was sucessful, yet my logic to determine this is flawed.
      if ($ftp->put($sub_log)) { print "FTP Put successful from server $ftp_server\n"; }else{ print "FTP Put Failed\n"; }
        You are already checking that the put/get succeeds in the original call:
        $ftp->put($sub_log) or ErrorOut("put failed ", $ftp->message);
        That will call ErrorOut if the put fails.
        You then $ftp->quit to close the connection, and call $ftp->put after that in the if statement, which will try uploading the file again (fails because the connection is closed).
        In that case, maybe capture the result of your put command and check against that:
        my $success = $ftp->put($sub_log); if ($success) { print "FTP Put successful from server $ftp_server\n"; } else { # handle and report errors }
        BTW...ErrorOut is a simple subroutine I use to write error contents to a log file and delete a program lockfile if it exists.
        sub ErrorOut { ################################################################## +######################## # # This subroutine write all STDERR to the log file and deletes th +e Lock File. # ################################################################## +######################## my $error = shift; print "$error\n"; # # Delete the Lock File # if (-e $lock_file) { if (unlink($lock_file) == 1) { print "Lock File $lock_file deleted successfully.\n\n"; } else { print "Lock File $lock_file could not be deleted.\nEnsure +the UID running this program has proper permissions\n"; # exit 1; } } # exit 1; } # End sub ErrorOut

        FTP Get Failed

        Huh? Where did that come from ... there's no get in the code you posted.

        -derby
Re: Error Checking with Net::FTP
by derby (Abbot) on Jan 07, 2008 at 18:52 UTC

    What happens when you do a manual FTP? Does it fail? Nothing is jumping out wrong with your code. There's nothing coming back from the debug? Hmmm ... then you either don't have permission to write the file or the ftp server disk is full.

    -derby

    update: Doh! I missed that second put ... pay no attention to me ... starX has the correct answer(s).