Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

In my daily life as a paid perl programmer (can there BE a better job?), I get to maintain perl of many different styles and techniques. I recently was creating a new process that is modeled on existing processes. So in approaching this project I was sure to try to leverage existing methods and hopefully, existing code.

Recently it was asked how to FTP through a firewall CPAN through a Firewall. This presents a code solution to that issue (actually, two solutions), beyond the simple response I gave at the time Re: CPAN through a Firewall.

Note that all the perl in this system pre-dates Perl 5, and my peers in this group on average have less than 6 months using Perl. So in addition to solving the problems at hand, my goal is also to help along these new perl programmers by showing them techniques that they will not find in their existing code (which currently makes use of no modules whatsoever). Also note that this CGI system used no warn, no strict and definately no taint, as well as a customized version of cgi-lib.pl. (but that is for another node).

What follows is a short description showing how this was being done currently, followed by the way I solved the same problem using newer perl tools (in this case, a CPAN module).

Note that I do not consider myself to be anywhere near a perl guru, and find it somewhat difficult to post meaningful replies that stand up to some of the amazing code I see posted by so many here on perlmonks. This is my attempt to humbly present my modest experiences in hope that at least some newbies might gain.

In this particular case, I need to FTP a datafile to a business partner through a firewall/proxy. In this application, the existing method for FTPing data outside was to invoke a system call to ftp, piping in the required user/pass/transfer commands, and piping the session messages to a flat file for later investigation, to confirm success.

Here is the code as it was being done today. Note I have trimmed the variable creation to conserve space, and hide real system names. Needless to say, the ftp is a bit non-intuitive, and if you're new to FTP/Unix/Perl (i.e. many of my peers) it's that much tougher to grok what's taking place.

system("ftp -n $gsRemoteMachine <<EOF> $gsStatusFile 2>&1\n\nuser $gsF +tpId$gsGateConnect $gsFtpPwd\nverbose\n$gsFtpMode\nput $gsFeedsDir$gs +FeedZipFile $gsRemoteDir$gsFeedZipFile\nclose\nbye\nEOF"); print "verifying FTP status..."; # Get FTP session record if(!open(STATUSFILE, $gsStatusFile)) { print "\n".$gsSysErr."Cannot open file $gsStatusFile. FTP failed.\n" +; email_error($gsEmailAdmin, $gsErrSys, $gsErrSys."Cannot open file $g +sStatusFile. FTP failed."); } @gaStatusLines = <STATUSFILE>; close(STATUSFILE); # check if "226 Transfer complete." occurs in gaStatusLines array for( $ii=0; $ii<=$#gaStatusLines; $ii++) { if(@gaStatusLines[$ii] eq "226 Transfer complete.\n") { $gnFtpFailed = 0; break; } } if( $gnFtpFailed ) { # "226 Transfer Complete" not found in gaStatusLines, so FTP failed. # print FTP fail message print "\n".$gsSysErr."FTP failed.\n"; print "\nFTP session:\n"; print @gaStatusLines; # send admin email email_error($gsEmailAdmin, $gsErrSys, $gsErrSys."FTP failed.\nFTP se +ssion:\n@gaStatusLines"); }

As you can see, alot of work has gone into determining what happened with the ftp session. It also relies on having some knowledge of ftp so that the commands are coded properly.

Enter Net::FTP

So I determined that Net::FTP was installed on our production server, but not our dev server, a simple message to the administrator rectified this problem.

Here is the code that replaced the above method of FTPing via Perl. Removed the system call (goodbye security issue), and the file IO. And solved the problem in less than half the lines of code. (Note I also introduced warn, strict and taint but that is for another node)

use Net::FTP; my $ftp; if (!($ftp = Net::FTP->new($gsGateMachine, -Passive => '1', -Firewall => $gsGateMachine)) ) { email_error($gsEmailAdmin, $gsErrSys, $gsErrSys."Connect failed. $@ +"); } $ftp->login("$gsFtpId\@$gsRemoteMachine","$gsFtpPwd"); if ( $ftp->put("$gsFeedsDir$gsFeedFile")) { push @ReportArray, "\nAJB FILE FTP SUCCESSFUL!\n"; else { push @ReportArray, "\n\tAJB FILE FTP FAILED $@\n"; email_error($gsEmailAdmin, $gsErrSys, $gsErrSys."FTP failed. $@"); }

Not only is it less typing, it's a bit easier to understand. And not having to open a status file to see what happened in the FTP session is a great improvement over the system call method.

Now I just hope I post this in the appropriate place...


In reply to Improving an FTP process by wardk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • 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.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (3)
As of 2024-03-28 17:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found