Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

map question...

by k2 (Scribe)
on Jun 16, 2003 at 20:49 UTC ( #266294=perlquestion: print w/replies, xml ) Need Help??

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

Hi all,
I'm trying to use the module Net::FTP::Recursive to get an entire catalog-structure from an FTP-server.
I used the rget-script that came along with the module and it works fine, when I connect to a Unix/Linux FTP...
BUT (there's allways a but) it does NOT work when I connect to a Novell FTP-server.
So I had a look at the script and came across this line:
(se below for the entire script)
$ftp->rget( map{($_, 1)} @ARGV);
The problem is that I can't figure out what the digit 1 does...
I think/hope/guess that the 1 refers to the digit 1 that shows that it's is a
file and not a directory when I do a dir on the Unix/Linux FTP-server.
If so I know that the Novell FTP-server has a "-" to indicate that it's a file and not a directory,
but I can't seem to get the script to work if I change the "1" to a "-".
I havde read the Map: The Basicsand the Complex Sorting
but neither of them has made me see the light ;-)
They talk about BLOCK's but ($_, 1) has me somewhat confused...

So now I hope that someone in the Monastary has the time to shed some light on my problem...

TIA
k2
----------------> CODE <---------------- #!/usr/bin/perl use Net::FTP::Recursive; #################################################################### # will assume just a few args, as well as validity. #################################################################### usage() unless @ARGV >= 5; $host = shift; $username = shift; $passwd = shift; $remote_path = shift; #where to grab from $local_path = shift; #where to put dir structure on local box. chdir $local_path or die "could not change dir to $local_path!"; $ftp = Net::FTP::Recursive->new($host, Debug => 1); $ftp->login($username, $passwd) or die "Could not log in!"; $ftp->binary(); $ftp->cwd($remote_path); $ftp->rget( map{($_, 1)} @ARGV); $ftp->quit; sub usage { my($name) = $0; $name =~ s#.*/##; print STDERR "Usage: $name <host> <username> <passwd> <remote_path> +<local_path>\n"; exit; }

Replies are listed 'Best First'.
Re: map question...
by sauoq (Abbot) on Jun 16, 2003 at 21:00 UTC
    $ftp->rget( map{($_, 1)} @ARGV);

    That map is essentially creating a hash where the keys are the elements in @ARGV and the values are 1's.

    For instance, if @ARGV held one element, "SymlinkIgnore" that code would result in a call to rget() just like $ftp-rget( SymlinkIgnore => 1); I think the man pages for Net::FTP::Recursive should clear it up from there.

    -sauoq
    "My two cents aren't worth a dime.";
    
Re: map question...
by djantzen (Priest) on Jun 16, 2003 at 20:57 UTC

    map BLOCK returns the last value in BLOCK for each element in the list of arguments. In this case it's returning a list where the first element is an item from @ARGV and the second is the number 1. Presumably the body of the rget method uses the list of elements to populate a hash where the key is the argument and the value set to 1 indicates that it ought to be in effect. There's nothing funky there, so I doubt that is the source of the problem. What may be a problem though is the actual arguments being passed in to @ARGV. What sort of errors are you seeing?


    "The dead do not recognize context" -- Kai, Lexx
      The errors I get is:

      Can't call method "originalLine" on an undefined value at /usr/lib/perl5/site_perl/5.8.0/Net/FTP/Recursive.pm line 55.

      There does not seem to be a problem before it should
      start to download the files,
      it says that Transfer Completes for the LIST command,
      so I guess I should take a look at the code in Recursive.pm
      and try to figure out what it expect in return from
      the FTP-server...
      (se below for the entire debug)

      Thanks
      /k2

      Net::FTP::Recursive: Net::FTP::Recursive(1.5) Net::FTP::Recursive: Net::FTP(2.65) Net::FTP::Recursive: Exporter(5.566) Net::FTP::Recursive: Net::Cmd(2.21) Net::FTP::Recursive: IO::Socket::INET(1.26) Net::FTP::Recursive: IO::Socket(1.27) Net::FTP::Recursive: IO::Handle(1.21) Net::FTP::Recursive=GLOB(0x8066ab4)<<< 220 Service Ready for new User Net::FTP::Recursive=GLOB(0x8066ab4)>>> user FTP_Backup Net::FTP::Recursive=GLOB(0x8066ab4)<<< 331 Password Needed for Login Net::FTP::Recursive=GLOB(0x8066ab4)>>> PASS .... Net::FTP::Recursive=GLOB(0x8066ab4)<<< 230 User FTP_Backup Logged in S +uccessfully Net::FTP::Recursive=GLOB(0x8066ab4)>>> TYPE I Net::FTP::Recursive=GLOB(0x8066ab4)<<< 200 TYPE Command OK I Net::FTP::Recursive=GLOB(0x8066ab4)>>> CWD . Net::FTP::Recursive=GLOB(0x8066ab4)<<< 250 Directory successfully chan +ged to "/data/" Net::FTP::Recursive=GLOB(0x8066ab4)>>> PORT 193,44,120,15,136,14 Net::FTP::Recursive=GLOB(0x8066ab4)<<< 200 PORT Command OK Net::FTP::Recursive=GLOB(0x8066ab4)>>> LIST Net::FTP::Recursive=GLOB(0x8066ab4)<<< 150 Opening data connection Net::FTP::Recursive=GLOB(0x8066ab4)<<< 226 Transfer Complete Can't call method "originalLine" on an undefined value at /usr/lib/per +l5/site_perl/5.8.0/Net/FTP/Recursive.pm line 55.

        I think that somehow you're getting an undef in your array of files (@files in the subroutine _rget) returned by parse_files, so when originalLine is called you see that warning error. It shouldn't happen when you turn off the "Debug" flag, but that's not a very good solution. If you have write access to that file I'd throw a couple of print statements in to see what you're actually getting for files, as well as for the return value of the call to Net::FTP::dir on line 55. If you don't have write access you can throw together a quick subclass that overrides that method and you can examine the information there.


        "The dead do not recognize context" -- Kai, Lexx
Re: map question...
by bbfu (Curate) on Jun 16, 2003 at 21:07 UTC

    As djantzen said, the map is building a list whose elements are alternatingly the arguments from the command line and 1's.

    What this appears to accomplish is that it allows you to pass strings such as 'FlattenTree' to the script and have them be interpreted correctly by rget().

    For example, the invocation:

    [johnsca@cory johnsca]$ rget FlattenTree SymlinkIgnore

    Will in effect call rget() as:

    $ftp->rget(FlattenTree => 1, SymlinkIgnore => 1);

    Which is how Net::FTP::Recursive expects the options to be passed. See the docs for Net::FTP::Recursive for more info on available options.

    bbfu
    Black flowers blossom
    Fearless on my breath

Re: map question...
by hossman (Prior) on Jun 17, 2003 at 05:20 UTC

    some people have pointed out that the "map" probably isn't your problem, so i'll skip that and point out what i think may be your problem.

    Net::FTP::Recursive is built ontp of Net::FTP .. if you look at the docs for that, you'll find this...

    Passive - If set to a non-zero value then all data transfers will be done using passive mode. This is not usually required except for some dumb servers, and some firewall configurations. This can also be set by the environment variable FTP_PASSIVE.
    I have no idea if Novell qualifies as a "dumb server" ... but it sounds likely. The only problems i've ever had in writting scripts that involve FPT have been from not using FTP_PASSIVE, or from servers on connections that suck so bad they died continuously)

    If passive mode doesn't work for you, then it would be usefull to see the "Debug=>1" output from the script when -- both when talking to the Novell server, and the serrver you got it to work on. If you post it, some friendly Monk might spot your problem.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://266294]
Approved by Tomte
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (3)
As of 2020-08-15 10:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Which rocket would you take to Mars?










    Results (78 votes). Check out past polls.

    Notices?