Which Net::FTP method for this?"

M

mailbox

I have a requirement that before data are sent to the remote host, an
arbitrary series of commands may have to be issued. Typically only a
"cd" to the destination directory will be issued, but sometimes there
will be other stuff, such as "umask", "sunique", and the like. For the
first version of my product, I got by with doing the "cd" using the
"cwd" method. But now the customer is breathing down my neck about the
complete implementation. All I see in the documentation for Net::FTP on
the CPAN Web site (perldoc hasn't been installed on our system) is the
method "quot" to handle an arbitrary command, and it doesn't want to do
a "cd". I got it to do quot("site umask 022") and it returned a status
of 2. When I tried quot("cd somedirectory"), though, it returned a
status of 5 and didn't do the cd. I don't know what the status return
codes mean. How should I proceed from here?
 
A

A. Sinan Unur

(e-mail address removed) wrote in @g43g2000cwa.googlegroups.com:
I have a requirement that before data are sent to the remote host, an
arbitrary series of commands may have to be issued. Typically only a
"cd" to the destination directory will be issued, but sometimes there
will be other stuff, such as "umask", "sunique", and the like. For the
first version of my product, I got by with doing the "cd" using the
"cwd" method. But now the customer is breathing down my neck about the
complete implementation.

If you are trying to get others' help with your paid job, you'll have to
do a better job of asking for it. Please see the posting guidelines for
this group for valuable information on how to help yourself, and help
others help you.
All I see in the documentation for Net::FTP on
the CPAN Web site (perldoc hasn't been installed on our system)

Why not?
is the method "quot" to handle an arbitrary command, and it doesn't
want to do a "cd". I got it to do quot("site umask 022") and it
returned a status of 2. When I tried quot("cd somedirectory"),
though, it returned a status of 5 and didn't do the cd. I don't
know what the status return codes mean. How should I proceed from
here?

Some thoughts:

* Read the FTP RFC
* Turn Net::FTP debugging on.
* Do read the docs carefully:

http://search.cpan.org/~gbarr/libnet-1.19/Net/FTP.pm:

quot (CMD [,ARGS])

Sinan
 
M

metaperl

My CPAN module Net::FTP::Common executes a hard-coded series of
commands before every API call...

In retrospect, a cleaner approach might've been to provide support and
pre and post callbacks instead.

You can check out the code at search.cpan.org and modify at will. I'm
too busy these days to modify it for you.
 
P

Paul Lalli

Do check a URL before you cite it. That one yields a NOT FOUND page.

Seems fine to me. Unless you and/or your newsreader mistook Sinan's
punctuation at the end of the URL to be part of the URL, rather than
indicating the heading from which the following text was obtained.

Way to make friends and influence people, by the way.

Paul Lalli
 
M

mailbox

You can check out the code at search.cpan.org and modify at will.

I did look at it, and it's an interesting product.

My query can probably be boiled down to this: why doesn't quot work for
cd? But I like to include context information to generate interest in
such a specialized question, even at the risk of eliciting unexpected
responses, such as the accusation elsewhere in the followups that I'm
trying to get others to do my work.

Anyway, the documenation for Net::FTP at CPAN says that quot works only
for "commands that do not require data connections". So my question can
be further boiled down to this: define "data connection" in such a way
that I can identify which FTP commands qualify and which do not.
(RFC959 is too abstract to be useful here.) Intuitively, I would expect
that get and put require a "data connection" and just about every other
command is for control.
 
A

A. Sinan Unur

(e-mail address removed) wrote in
I did look at it, and it's an interesting product.

My query can probably be boiled down to this: why doesn't quot work
for cd? But I like to include context information to generate interest
in such a specialized question, even at the risk of eliciting
unexpected responses, such as the accusation elsewhere in the
followups that I'm trying to get others to do my work.

Cute. Did you actually try fixing the error I pointed out in your script?

Sinan
 
S

Sisyphus

..
..
My query can probably be boiled down to this: why doesn't quot work for
cd?

I think it's a case of "Why doesn't the FTP Server understand 'cd' ?" - and
that's an off-topic question on a perl forum. I'd answer that question
except that I don't know the correct answer :)

Of course wrt 'cd' specifically, there's no *need* for the FTP Server to
understand it, as there's already the FTP commands (and Net::FTP methods)
'cwd' and 'cdup' to handle directory changes. They should be used instead.
But I like to include context information to generate interest in
such a specialized question, even at the risk of eliciting unexpected
responses, such as the accusation elsewhere in the followups that I'm
trying to get others to do my work.

Best to just ignore the inflammatory stuff and look for the *useful*
remarks. Sinan did recommend that you turn on debugging - and that's good
advice. (If you don't know how to do that, just specify Debug=>1 as one of
the arguments to the new() constructor - and you'll get more verbose
feedback from the FTP Server.) There's also a hint that the syntax of your
quot() call is incorrect .... but that one eludes me.

Basically, I gather that what you're wanting to do is to be able to execute
commands that are not supported by the FTP protocol.
You might find something useful on
http://cpan.uwinnipeg.ca/htdocs/libnet/libnetFAQ.html . Especially "How can
I change the permissions of a file on a remote server ?" and "Is it possible
to change the file permissions of a file on an FTP server ?" - both of which
provide slightly different ways of executing a command (chmod) that is not
supported by the FTP protocol. (Note that there's no guarantee that the FTP
Server will oblige - though both incantations worked with the FTP Server
that I use.)

I suspect that "the customer" may be harrassing the wrong person. If the FTP
Server doesn't understand some command, then there's nothing you can do
about it. You should simply tell "the customer" to take it up with the
person(s) in charge of the FTP Server.

Cheers,
Rob
 
A

A. Sinan Unur

There's also a hint that the syntax of your quot() call is
incorrect .... but that one eludes me.

Well, the docs say

<URL:http://search.cpan.org/~gbarr/libnet-1.19/Net/FTP.pm>:

quot (CMD [,ARGS])

whereas the OP is using:

quot("cd somedirectory")

according to his post.

Looking at the source for Net::FTP:

sub quot
{
my $ftp = shift;
my $cmd = shift;

$ftp->command( uc $cmd, @_);
$ftp->response();
}

So, passing the string "cd somedirectory" to quot would result in
"CD SOMEDIRECTORY" being sent to the server. I doubt that's what the OP
intended.

I am, of course, not sure if this will help, but without this error
fixed, I see no point in looking elsewhere.

Of course, actually turning debugging on for Net::FTP probably would
have revealed what was actually being sent to the server.

Sinan
 
S

Sisyphus

..
..
Of course, actually turning debugging on for Net::FTP probably would
have revealed what was actually being sent to the server.

It also gives you an error message from the server (which you otherwise
don't see):

Net::FTP=GLOB(0x921f28)>>> CD w32perl
Net::FTP=GLOB(0x921f28)<<< 500 CD not understood

For me, there is no correct way to do a 'cd' using Net::FTP. I tried:

$ftp->quot("site cd", "w32perl");
$ftp->quot("cd", "w32perl");
$ftp->quot("site cd w32perl");
$ftp->quot("cd w32perl");
$ftp->site("cd", "w32perl");
$ftp->site("cd w32perl");

Although the actual command varied, it always produced "500 <command> not
understood".

When I look at the libnet faq I find the following examples (both of which
work for me):
$ftp->quot('site chmod 0777',$filename);
$ftp->site('chmod','0775',$file);

Note that in the first of those two commands '0777' is part of the CMD - it
is *not* provided as an argument.

From the Net::FTP documentation, I would have expected that the quot() call
be written as:
$ftp->quot('chmod', '0777', $filename);
But that produces, for me:
Net::FTP=GLOB(0x921f34)<<< 500 CHMOD not understood

However, the following works fine:
$ftp->quot('site chmod', '0777',$filename);

Note that this time '0777' *is* being provided as an argument.

My hunch is that quot('site cd somedirectory') would work just as well as
quot('site cd', 'somedirectory') .... except that 'cd' is not supported (on
the FTP Server I use, at least - with or without the 'site') .... which
makes that conjecture a little absurd :)

Incidentally, to the op:
A return of 5 is short for 500 (basically means error, I think), a return of
2 is short for 200 (basically means ok, I think).

Cheers,
Rob
 
A

A. Sinan Unur

.
.

It also gives you an error message from the server (which you
otherwise don't see):

Net::FTP=GLOB(0x921f28)>>> CD w32perl
Net::FTP=GLOB(0x921f28)<<< 500 CD not understood

For me, there is no correct way to do a 'cd' using Net::FTP. I tried:

Well, the only FTP server I have access to does not accept cd, but using

$ftp->quot(qw(cwd public_html));

works for me.

....
When I look at the libnet faq I find the following examples (both of
which work for me):
$ftp->quot('site chmod 0777',$filename);
$ftp->site('chmod','0775',$file);

Note that in the first of those two commands '0777' is part of the CMD
- it is *not* provided as an argument.

From the Net::FTP documentation, I would have expected that the quot()
call be written as:
$ftp->quot('chmod', '0777', $filename);
But that produces, for me:
Net::FTP=GLOB(0x921f34)<<< 500 CHMOD not understood

Interesting. For me, that seems to work:

#!/usr/bin/perl

use strict;
use warnings;

my %account = (
host => '...',
name => '...',
pass => '...',
);

use Net::FTP;

my $ftp = Net::FTP->new($account{host}, Debug => 1)
or die "Cannot connect to '$account{host}': $@\n";

$ftp->login($account{name}, $account{pass})
or die "Cannot login: ", $ftp->message, "\n";

$ftp->quot(qw(site chmod 0777 test.txt));

$ftp->quit;

__END__

....
Net::FTP=GLOB(0x1a567a0)>>> SITE chmod 0777 test.txt
Net::FTP=GLOB(0x1a567a0)<<< 200 SITE CHMOD command successful
Net::FTP=GLOB(0x1a567a0)>>> QUIT
Net::FTP=GLOB(0x1a567a0)<<< 221 Goodbye.

However, the following works fine:
$ftp->quot('site chmod', '0777',$filename);

Note that this time '0777' *is* being provided as an argument.

It should not make any difference, though. Net::FTP->quot uses
Net::CMD->command which joins all its arguments using a space.

....
Incidentally, to the op:
A return of 5 is short for 500 (basically means error, I think), a
return of 2 is short for 200 (basically means ok, I think).

Which, of course, are explained by Net::FTP and RFC 959.

Sinan
 
M

mailbox

A. Sinan Unur said:
Well, the only FTP server I have access to does not accept cd, but using

$ftp->quot(qw(cwd public_html));

works for me.


I've never connected to an FTP server that didn't accept "cd" entered
at the prompt.

The customer wants me to be able to process an arbitrary series of
control commands fed to me as a single string before getting or putting
data, e.g. "sunique;site umask 022;cd somedirectory;". I had hoped to
be able to make successive quot calls, but I'll just have to
put in some extra code to process a "cd" either the way you've shown
above or with a call to the cwd function. A minor irritation in the
end, but I still wanted to make sure there was no more parsimonious
alternative.

Thanks to you and Sisyphus for being generous with your time in
checking out the situation.
 
E

Eric Schwartz

I've never connected to an FTP server that didn't accept "cd" entered
at the prompt.

More accurately, you've never used an FTP client that didn't translate
"cd" into "CWD" for you. CWD is the raw FTP protocol command to
change the current working directory; you've been lead down the
primrose path by helpful clients that turn 'cd foo' into "CWD foo" for
you.

-=Eric
 
A

A. Sinan Unur

(e-mail address removed) wrote in
The customer wants me to be able to process an arbitrary series of
control commands fed to me as a single string before getting or
putting data, e.g. "sunique;site umask 022;cd somedirectory;". I had
hoped to be able to make successive quot calls,

You might benefit from using a different tool. Instead of Net::FTP, I
would look into Expect:

<URL:http://search.cpan.org/~rgiersig/Expect-1.15/Expect.pod>

Sinan
 
H

harryfmudd [AT] comcast [DOT] net

I've never connected to an FTP server that didn't accept "cd" entered
at the prompt.

A more correct way to say this is "I've never used an FTP client that
didn't accept 'cd' entered at the prompt." What gets sent to the server
may be (and is in this case) something different.
The customer wants me to be able to process an arbitrary series of
control commands fed to me as a single string before getting or putting
data, e.g. "sunique;site umask 022;cd somedirectory;". I had hoped to
be able to make successive quot calls, but I'll just have to
put in some extra code to process a "cd" either the way you've shown
above or with a call to the cwd function. A minor irritation in the
end, but I still wanted to make sure there was no more parsimonious
alternative.

Thanks to you and Sisyphus for being generous with your time in
checking out the situation.

The problem appears to be that the customary commands to the FTP client
do not necessarily have the same names as the underlying FTP protocol
commands. Two alternatives: using the protocol names, or translating the
command names. The former would go something like this:

my $client = Net::FTP->new (...)

# ... some code to set things up ...

my $what_to_do = 'site umask o22;cwd somedirectory;'
foreach my $cmd (split ';', $what_to_do) {
next unless $cmd; # handle trailing ';'
my @args = split '\s+', $cmd;
my $verb = shift @args;
$client->$verb (@args); # Call method of your choice.
}


If you're getting fancy, you might want to use Text::parseWords rather
than split().

Note that I called the relevant method via the contents of $verb. This
appears to work even if you have 'strict' and 'warnings' turned on. I
have not dealt with error trapping (hint: $client->can ($verb)).

But calling the commands what you want may not need to be all that
difficult:

my %alias = (cd => 'cwd');

and then, after determining the verb, do something like

$verb = $alias{$verb} if $alias{$verb};
The thing is, there are a number of the customary commands that simply
configure the client. And 'sunique' appears to be one of them. If I were
implementing it using Net::FTP, I would have it tell the client to use
put_unique() rather than put().

Tom Wyant
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,176
Messages
2,570,948
Members
47,500
Latest member
ArianneJsb

Latest Threads

Top