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

If you can tolerate a question from an arch-newbie, I've got one. What I'm trying to do ftp a file resident on my web server to a remote site. I'm having trouble specifying the sever-local path/filename. Here's the code in its most basic version:
use Net::FTP; $ftp = Net::FTP->new("ftp.xyz.com", Timeout => 300, Debug => 1) or + die "Cannot contact $host: $!"; $ftp->login("xxxx",'yyyy'); $ftp->cwd("/"); $ftp->put("/directory-a/filename-b"); $ftp->quit;
Here's the output from my error log:
Net::FTP>>> Net::FTP(2.75) Net::FTP>>> Exporter(5.58) Net::FTP>>> Net::Cmd(2.26) Net::FTP>>> IO::Socket::INET(1.31) Net::FTP>>> IO::Socket(1.29) Net::FTP>>> IO::Handle(1.25) Net::FTP=GLOB(0x82f8768)<<< 220---------- Welcome to Pure-FTPd ------- +--- Net::FTP=GLOB(0x82f8768)<<< 220-You are user number 318 of 1000 allowe +d. Net::FTP=GLOB(0x82f8768)<<< 220-Local time is now 10:41. Server port: +21. Net::FTP=GLOB(0x82f8768)<<< 220-This is a private system - No anonymou +s login Net::FTP=GLOB(0x82f8768)<<< 220 You will be disconnected after 60 seco +nds of inactivity. Net::FTP=GLOB(0x82f8768)>>> user xxxx Net::FTP=GLOB(0x82f8768)<<< 331 User xxxx OK. Password required Net::FTP=GLOB(0x82f8768)>>> PASS .... Net::FTP=GLOB(0x82f8768)<<< 230-User xxxx has group access to: 1000 + Net::FTP=GLOB(0x82f8768)<<< 230 OK. Current restricted directory is / Net::FTP=GLOB(0x82f8768)>>> CWD / Net::FTP=GLOB(0x82f8768)<<< 250 OK. Current directory is / Cannot open Local file directory-a/filename-b: No such file or directo +ry at /home/users/web/blah/cgi-bin/script.cgi line 10 Net::FTP=GLOB(0x82f8768)>>> QUIT Net::FTP=GLOB(0x82f8768)<<< 221-Goodbye. You uploaded 0 and downloaded + 0 kbytes. Net::FTP=GLOB(0x82f8768)<<< 221 Logout.
I've tried various ways of specifying the path including the absolute path on my server to the file without success. However, just now I've figured out that using the absolute path gets past the "Cannot open Local file directory-a/filename-b" message but generates a different error: Can't call method "sockport" on an undefined value at /usr/local/lib/perl5/5.8.8/Net/FTP.pm line 837. Does this indicate a problem with the server configuration? Any suggestions are appreciated.

Replies are listed 'Best First'.
Re: CGI/FTP Put question
by almut (Canon) on Jul 17, 2008 at 18:38 UTC
    Can't call method "sockport" on an undefined value

    That's probably because the preceding bind/listen call failed, which in turn might be because your webserver process is not allowed to create the respective listening socket to which the FTP server (when operating in the default "active" mode) is then meant to establish a second connection to (used to transfer the data).

    In other words, you could try passive mode (which is not guaranteed to work either, though). I.e.

    $ftp = Net::FTP->new("ftp.xyz.com", Passive => 1, Timeout => 300, Debu +g => 1)

    Quote from the docs:

    FTP servers can work in passive or active mode. Active mode is when you want to transfer data you have to tell the server the address and port to connect to. Passive mode is when the server provides the address and port and you establish the connection. With some firewalls active mode does not work as the server cannot connect to your machine (because you are behind a firewall) and the fi +rewall does not re-write the command. In this case you should set ftp_ext_pas +sive to a true value.
Re: CGI/FTP Put question
by pileofrogs (Priest) on Jul 17, 2008 at 18:46 UTC

    FTP is a @#^$@%.

    Where is the script running relative to the 'webserver' and ftp.xyz.com?

    Is directory-a/filename-b the name on your webserver or on ftp.xyz.com?

    The message you get when you specify the full path probably indicates that the connection failed in there somewhere (and Net::FTP should do a better job of reporting that..) So either your full path somehow broke Net::FTP or you added an extra bug somewhere else while you were adding the full path.

Re: CGI/FTP Put question
by DrWho_100 (Acolyte) on Jul 17, 2008 at 20:12 UTC
    Great call almut! It works in passive mode. Thanks.
Re: CGI/FTP Put question
by eosbuddy (Scribe) on Jul 17, 2008 at 19:01 UTC
    I believe your problem stems from the cwd directive... cwd should be set to the home directory of the user xxxx (or whatever)... by setting it to /, what the protocol is doing is logging in and changing directory to / and then trying to create the path that you give. My 2 cents :-) Update: please remember that you won't be able to ftp in as the user: root :-) (so you cannot technically go to the folder /)
Re: CGI/FTP Put question
by jethro (Monsignor) on Jul 17, 2008 at 18:56 UTC
    Very true that @#^$@%. If possible use scp for that file transfer.