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

Hi, I'm not a perl programmer but I'm trying to modify an existing script from Net::FTP to NET::FTPSSL. Now there are problem to get the files. I got this error: syswrite() on closed filehandle GEN0 at Can't write command on socket: Bad file number This is part of the code:
# GET FILE LIST if ( !$error_flag ) { if ( !$debug ) { @files = $ftp->list() or $error_flag = + 1; $ftp->quit if $error_flag; } else { opendir( DIR, "$debug_ftp_directory/$d +irectory_local" ) or $error_flag = 1; @files = readdir(DIR); closedir(DIR); } $report = $report . " ERROR: Can't get file l +ist $!\n" if $error_flag; $error_cnt++ if $error_flag; } # GET ALL FILES (*.enc) TO LOCAL DIRECTORY, DELETE THE +M ON SERVER foreach $file (@files) { if ( !$error_flag && $file =~ m/\.enc$/ ) { $report = $report . " Retrieving file + $file\n"; if ( !$debug ) { $ftp->get($file) or $error_fla +g = 1; $ftp->quit if $error_flag; $ftp->delete($file) or $error_ +flag = 1; $ftp->quit if $error_flag; } else { move( "$debug_ftp_directory/$d +irectory_local/$file", '.' ) or $error_flag = 1; } if ( !$error_flag ) { $downloaded_cnt++; } else { $report = $report . " ERROR: Can't re +trieve file $file $!\n"; $error_cnt++; } } } if ( ( !$error_flag ) && ( !$debug ) ) { $ftp->quit; }
Would be greatful if someone can help me. This worked out with Net::FTP Thanks in advance Bettan

Replies are listed 'Best First'.
Re: FTPSSL Bad file number
by Anonymous Monk on Mar 03, 2015 at 15:23 UTC

    Please provide exact error messages, as you don't tell us which line of your example code the error happens (How do I post a question effectively?). I can only make a guess:

    $ftp->get($file) or $error_flag = 1; $ftp->quit if $error_flag; $ftp->delete($file) or $error_flag = 1; $ftp->quit if $error_flag;

    This logic says that if $ftp->get($file) returns a false value, to call $ftp->quit, and then call $ftp->delete($file), even though by then the connection might be closed. Also, although apparently not related to your error message:

    opendir( DIR, "$debug_ftp_directory/$directory_local" ) or $error_flag = 1; @files = readdir(DIR); closedir(DIR);

    That's not quite right as it will attempt to readdir and closedir even if the opendir fails. It's usually better to opendir ... or die ... and handle the error elsewhere.

    In general, you seem to be relying quite heavily on $error_flag to control the flow of your program, which leads to lots of repeated statements (if ( !$error_flag ... and $ftp->quit) and logic that can easily break if you later insert more statements into the code. I would suggest you look into flow control statements like last and next, as well as breaking your code down into subroutines from which you can return. Even dieing or croaking combined with Try::Tiny (or similar) is a good method for exception handling - for example, you could place your error counting/reporting into a catch block, $ftp->quit into a finally block, and then just die from the main code in the try block in case of errors.

      Exact error message:
      syswrite() on closed filehandle GEN0 at /usr/perl5/site_perl/5.8.4/Net +/FTPSSL.pm line 2673. Can't write command on socket: Bad file number at /usr/local/bin/debit +ech line 158 syswrite() on closed filehandle GEN0 at /usr/perl5/site_perl/5.8.4/Net +/FTPSSL.pm line 2673. Can't write command on socket: Bad file number at /usr/local/bin/debit +ech line 159 Debitech File Transfer started at Wed Mar 4 20:59:02 2015 Downloaded files: 0 Finished files: 0 Errors: 1 lwbv --------------- Retrieving file -rwxr-xr-x 1 260 410 2071 Mar + 3 10:31 B0000198800028222.xml.enc ERROR: Can't retrieve file -rwxr-xr-x 1 260 410 + 2071 Mar 3 10:31 B0000198800028222.xml.enc Bad file number

        My crystal ball is in the shop... what do lines 158 and 159 of /usr/local/bin/debitech say?

        Have you tried turning on the options "Croak", "Debug" or "Trace" of Net::FTPSSL?

Re: FTPSSL Bad file number
by Anonymous Monk on Mar 03, 2015 at 17:32 UTC