CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Intermediate:
Ftp directory listing not working with paths containing spaces

 



turnerr
Novice

Jan 1, 2014, 7:27 AM

Post #1 of 18 (2180 views)
Ftp directory listing not working with paths containing spaces Can't Post

I have a script that syncs up directory structures using ftp but am having a problem with it when the path names contain spaces. I have tried everything I can think of and still cannot get it to work. Any help would be greatly appreciated.

Here's a code snippet:

Code
my $ftp = new Net::FTP ($opt_s, 
Debug => $opt_d,
Passive => $opt_P,
);

die "Failed to connect to server '$opt_s': $!\n" unless $ftp;
die "Failed to login as $opt_u\n" unless $ftp->login($opt_u, $opt_p);
die "Cannot change directory to $opt_r\n" unless $ftp->cwd($opt_r);
warn "Failed to set binary mode\n" unless $ftp->binary();

print "connected\n" if $opt_v;

sub scan_ftp
{
my $ftp = shift;
my $path = shift;
my $rrem = shift;

print "path $path\n"; if ($path =~ / /)
{
$path =~ s/ /\\ /g;
}

print "path2 $path\n";

my $t = $path;
$t =~ s/ /\\ /g;


my $rdir = length($path) ? $ftp->dir($path) : $ftp->dir();

return unless $rdir and @$rdir;
print "after return\n";

for my $f (@$rdir)
{
print "1 $f\n";
next if $f =~ m/^d.+\s\.\.?$/;

my $n = (split(/\s+/, $f, 9))[8]; next unless defined $n;


my $name = '';
$name = $path . '/' if $path;
$name .= $n;


if ($opt_i and $name =~ m/$opt_i/)
{
print "ftp: IGNORING $name\n" if $opt_d;
next;
}

next if exists $rrem->{$name};

my $mdtm = ($ftp->mdtm($name) || 0) + $opt_o;
my $size = $ftp->size($name) || 0;
my $type = substr($f, 0, 1);
$type =~ s/-/f/;

warn "ftp: adding $name ($mdtm, $size, $type)\n" if $opt_d;

$rrem->{$name} =
{
mdtm => $mdtm,
size => $size,
type => $type,
};

scan_ftp($ftp, "$name", $rrem) if $type eq 'd';
}
}



Here's some debugging output:

1 drwxr----- 2 oracle oinstall 512 Aug 26 14:48 New folder
Net::FTP=GLOB(0x31364)>>> MDTM cart/New folder^M
Net::FTP=GLOB(0x31364)<<< 550 cart/New folder: not a plain file.
Net::FTP=GLOB(0x31364)>>> SIZE cart/New folder^M
Net::FTP=GLOB(0x31364)<<< 550 cart/New folder: not a plain file.
ftp: adding cart/New folder (0, 0, d)
path cart/New folder
path2 cart/New\\ folder
Net::FTP=GLOB(0x31364)>>> PORT 192,168,7,233,176,34^M
Net::FTP=GLOB(0x31364)<<< 200 PORT command successful.
Net::FTP=GLOB(0x31364)>>> LIST cart/New\\ folder^M
Net::FTP=GLOB(0x31364)<<< 150 Opening BINARY mode data connection for /bin/ls.
Net::FTP=GLOB(0x31364)<<< 226 Transfer complete.
1 -rwxr----- 1 oracle oinstall 3129 Dec 3 2012 ShoppingCart.class
Net::FTP=GLOB(0x31364)>>> MDTM cart/ShoppingCart.class^M
Net::FTP=GLOB(0x31364)<<< 213 20121203182147
Net::FTP=GLOB(0x31364)>>> SIZE cart/ShoppingCart.class^M
Net::FTP=GLOB(0x31364)<<< 213 3129
ftp: adding cart/ShoppingCart.class (1354558907, 3129, f)
1 -rwxr----- 1 oracle oinstall 3393 Jun 18 2013 ShoppingCartAccount.class
Net::FTP=GLOB(0x31364)>>> MDTM cart/ShoppingCartAccount.class^M


This is what the directory structure in question looks like:

/usr2/prod/app/oracle/Oraas/j2ee/act_webdev/applications/act_webdev/act_webdev/WEB-INF/classes/act/payment/cart
.:
total 38
drwxr----- 2 oracle oinstall 512 Aug 26 14:48 New folder
-rwxr----- 1 oracle oinstall 3393 Jun 18 2013 ShoppingCartAccount.class
-rwxr----- 1 oracle oinstall 8491 Jun 18 2013 ShoppingCartAccountInformation.class
-rwxr----- 1 oracle oinstall 3129 Dec 3 2012 ShoppingCart.class
-rw-r----- 1 oracle oinstall 112 Jan 1 09:12 tst

./New folder:
total 28
-rwxr----- 1 oracle oinstall 3645 Dec 3 2012 ShoppingCartAccount.class
-rwxr----- 1 oracle oinstall 9596 Mar 5 2013 ShoppingCartAccountInformation.class


Thanks,
Rob


(This post was edited by FishMonger on Jan 1, 2014, 7:48 AM)


FishMonger
Veteran / Moderator

Jan 1, 2014, 8:54 AM

Post #2 of 18 (2175 views)
Re: [turnerr] Ftp directory listing not working with paths containing spaces [In reply to] Can't Post

I've edited your post to add the code tags around your code. Please use them in the future when posting your code.

First step is to fix your indentation on those print statements to improve the readability.

Don't put more than 1 statement in a line. Multiple statements on a single line make the code less readable.

Use the Data::Dumper module to dump out the $rdir var as soon as it is assigned to make sure it holds what you expect. You may even want to use Dumper to output your other debugging statements to verify that those vars are exactly what you expect.

With the occasional exception of loop iterators, don't use single letter vars such as your $t, $f and $n. Var names should describe what they contain. Those single letters don't tell me (or anyone else) what kind of data they hold.

Why are you defining that $t var? It's not being used once it's assigned.

Your "after return\n" print statement is not in the output you posted. That tells me that the code you posted is not the exact same code which produced that output.


turnerr
Novice

Jan 1, 2014, 6:40 PM

Post #3 of 18 (2167 views)
Re: [FishMonger] Ftp directory listing not working with paths containing spaces [In reply to] Can't Post

I had defined the $t var for some debugging that I took out. The 'after return' is not printing because of the space in the path. It does print for directories which don't contain spaces. I didn't include all of the output because it's quite large.

Thanks.


FishMonger
Veteran / Moderator

Jan 2, 2014, 6:56 AM

Post #4 of 18 (2158 views)
Re: [turnerr] Ftp directory listing not working with paths containing spaces [In reply to] Can't Post

The only reason for that print statement to not be executed would be if the return statement above it was executed.

That would happen if this statement failed to return a dir listing.

Code
my $rdir = length($path) ? $ftp->dir($path) : $ftp->dir();


If we focus on that statement, the problem is most likely with $ftp->dir($path).

Have you tried quoting $path?

$ftp->dir("$path")
or
$ftp->dir("'$path'")

That second one is using 2 sets of quotes. Double quotes on the outside to allow interpolation and single quotes inside the double quotes to quote the path string.

I have not been able to test any possible solutions because we disable ftp on our servers for security and PCI compliance. But will see if I can find one of our servers that still has ftp enabled.

While I'm on that (security) subject, let me suggest that you switch over to using Net::SSH2::FTP.
http://search.cpan.org/~rkitover/Net-SSH2-0.53/lib/Net/SSH2/SFTP.pm

The sub you posted isn't doing any ftp (unless you've stripped out that portion of the sub from your post), and if that's the case, why use the Net::FTP module. Net::SSH2 would seem to be a better choice.


turnerr
Novice

Jan 2, 2014, 7:46 AM

Post #5 of 18 (2155 views)
Re: [FishMonger] Ftp directory listing not working with paths containing spaces [In reply to] Can't Post

Using double quotes produced the same results as no quotes - no listing is produced for paths containing spaces. If I used single quotes inside of double quotes, no listing is produced for any path regardless of whether it contains spaces. I used Data::Dumper to dump the rdir var and it appears that it contains nothing then the path contains spaces. Here is some output:
1 drwxr----- 3 oracle oinstall 512 Jan 1 09:11 cart
Net::FTP=GLOB(0x313dc)>>> MDTM cart^M
Net::FTP=GLOB(0x313dc)<<< 550 cart: not a plain file.
Net::FTP=GLOB(0x313dc)>>> SIZE cart^M
Net::FTP=GLOB(0x313dc)<<< 550 cart: not a plain file.
ftp: adding cart (0, 0, d)
path cart
Net::FTP=GLOB(0x313dc)>>> PORT 192,168,7,233,253,66^M
Net::FTP=GLOB(0x313dc)<<< 200 PORT command successful.
Net::FTP=GLOB(0x313dc)>>> LIST cart^M
Net::FTP=GLOB(0x313dc)<<< 150 Opening BINARY mode data connection for /bin/ls.
Net::FTP=GLOB(0x313dc)<<< 226 Transfer complete.
rdir var for cart
$VAR1 = [
'total 38',
'drwxr----- 2 oracle oinstall 512 Aug 26 14:48 New folder',
'-rwxr----- 1 oracle oinstall 3129 Dec 3 2012 ShoppingCart.class',
'-rwxr----- 1 oracle oinstall 3393 Jun 18 2013 ShoppingCartAccount.class',
'-rwxr----- 1 oracle oinstall 8491 Jun 18 2013 ShoppingCartAccountInformation.class',
'-rw-r----- 1 oracle oinstall 686 Jan 1 09:12 tst'
];
after return
1 total 38
1 drwxr----- 2 oracle oinstall 512 Aug 26 14:48 New folder
Net::FTP=GLOB(0x313dc)>>> MDTM cart/New folder^M
Net::FTP=GLOB(0x313dc)<<< 550 cart/New folder: not a plain file.
Net::FTP=GLOB(0x313dc)>>> SIZE cart/New folder^M
Net::FTP=GLOB(0x313dc)<<< 550 cart/New folder: not a plain file.
ftp: adding cart/New folder (0, 0, d)
path cart/New folder
Net::FTP=GLOB(0x313dc)>>> PORT 192,168,7,233,253,67^M
Net::FTP=GLOB(0x313dc)<<< 200 PORT command successful.
Net::FTP=GLOB(0x313dc)>>> LIST cart/New folder^M
Net::FTP=GLOB(0x313dc)<<< 150 Opening BINARY mode data connection for /bin/ls.
Net::FTP=GLOB(0x313dc)<<< 226 Transfer complete.
rdir var for cart/New folder
$VAR1 = [];
1 -rwxr----- 1 oracle oinstall 3129 Dec 3 2012 ShoppingCart.class
Net::FTP=GLOB(0x313dc)>>> MDTM cart/ShoppingCart.class^M
Net::FTP=GLOB(0x313dc)<<< 213 20121203182147
Net::FTP=GLOB(0x313dc)>>> SIZE cart/ShoppingCart.class^M


FishMonger
Veteran / Moderator

Jan 2, 2014, 9:06 AM

Post #6 of 18 (2143 views)
Re: [turnerr] Ftp directory listing not working with paths containing spaces [In reply to] Can't Post

I found an ftp server to test on and discovered that if you remove the regex portion that escapes the path, it will work correctly.

Here is my complete working test.

Code
#!/usr/bin/perl 

use strict;
use warnings;
use Net::FTP;
use Getopt::Std;
use Data::Dumper;

our ($opt_s, $opt_d, $opt_P, $opt_r, $opt_u, $opt_p, $opt_i, $opt_o, $opt_v);

getopt('sdPrupiov');

my $ftp = new Net::FTP(
$opt_s,
Debug => $opt_d,
Passive => $opt_P,
);

die "Failed to connect to server '$opt_s': $!\n" unless $ftp;
die "Failed to login as $opt_u\n" unless $ftp->login( $opt_u, $opt_p );
die "Cannot change directory to $opt_r\n" unless $ftp->cwd($opt_r);
warn "Failed to set binary mode\n" unless $ftp->binary();

print "connected\n" if $opt_v;
scan_ftp($ftp, '.');


sub scan_ftp {
my $ftp = shift;
my $path = shift;
my $rrem = shift;

print "path $path\n";

my $rdir = length($path) ? $ftp->dir($path) : $ftp->dir();

return unless $rdir and @$rdir;
print "after return\n";

for my $f (@$rdir) {
print "1 $f\n";
next if $f =~ m/^d.+\s\.\.?$/;

my $n = ( split( /\s+/, $f, 9 ) )[8];
next unless defined $n;

my $name = '';
$name = $path . '/' if $path;
$name .= $n;

if ( $opt_i and $name =~ m/$opt_i/ ) {
print "ftp: IGNORING $name\n" if $opt_d;
next;
}

next if exists $rrem->{$name};

my $mdtm = ( $ftp->mdtm($name) || 0 ) + $opt_o;
my $size = $ftp->size($name) || 0;
my $type = substr( $f, 0, 1 );
$type =~ s/-/f/;

warn "ftp: adding $name ($mdtm, $size, $type)\n" if $opt_d;

$rrem->{$name} = {
mdtm => $mdtm,
size => $size,
type => $type,
};

scan_ftp( $ftp, "$name", $rrem ) if $type eq 'd';
}
}



Code
[root@ftpserver ~]# ll -R 
.:
total 8
drwxr-xr-x 2 root root 4096 Jan 2 08:51 New folder

./New folder:
total 747820
-rw-r--r-- 1 root root 95597911 Dec 27 06:42 u00000952_2013122403_usd_gcsv3.csv
-rw-r--r-- 1 root root 95614427 Dec 27 06:48 u00000952_2013122406_usd_gcsv3.csv
-rw-r--r-- 1 root root 95628571 Dec 27 06:49 u00000952_2013122409_usd_gcsv3.csv
-rw-r--r-- 1 root root 95661954 Dec 27 06:50 u00000952_2013122412_usd_gcsv3.csv
-rw-r--r-- 1 root root 95617432 Dec 27 06:50 u00000952_2013122415_usd_gcsv3.csv
-rw-r--r-- 1 root root 95612049 Dec 27 06:50 u00000952_2013122418_usd_gcsv3.csv
-rw-r--r-- 1 root root 95599819 Dec 27 06:50 u00000952_2013122421_usd_gcsv3.csv
-rw-r--r-- 1 root root 95602518 Dec 27 06:50 u00000952_2013122500_usd_gcsv3.csv



Code
c:\test>turnerr.pl -s ftpserver -u fishmonger -p password -v 1 -o 0 -r . 
connected
path .
after return
1 drwxr-xr-x 2 root root 4096 Jan 2 16:51 New folder
path ./New folder
after return
1 -rw-r--r-- 1 root root 95597911 Dec 27 14:42 u00000952_2013122403_usd_gcsv3.csv
1 -rw-r--r-- 1 root root 95614427 Dec 27 14:48 u00000952_2013122406_usd_gcsv3.csv
1 -rw-r--r-- 1 root root 95628571 Dec 27 14:49 u00000952_2013122409_usd_gcsv3.csv
1 -rw-r--r-- 1 root root 95661954 Dec 27 14:50 u00000952_2013122412_usd_gcsv3.csv
1 -rw-r--r-- 1 root root 95617432 Dec 27 14:50 u00000952_2013122415_usd_gcsv3.csv
1 -rw-r--r-- 1 root root 95612049 Dec 27 14:50 u00000952_2013122418_usd_gcsv3.csv
1 -rw-r--r-- 1 root root 95599819 Dec 27 14:50 u00000952_2013122421_usd_gcsv3.csv
1 -rw-r--r-- 1 root root 95602518 Dec 27 14:50 u00000952_2013122500_usd_gcsv3.csv



turnerr
Novice

Jan 2, 2014, 9:38 AM

Post #7 of 18 (2137 views)
Re: [FishMonger] Ftp directory listing not working with paths containing spaces [In reply to] Can't Post

I don't understand your post. Are you saying not to escape the space in the path? If so, I've already removed that code and it still doesn't work. What path are you initially accessing? I have found that I can initially get into a path that contains spaces in the name. However, any subdirectories that contain spaces do not return a directory listing.


FishMonger
Veteran / Moderator

Jan 2, 2014, 10:35 AM

Post #8 of 18 (2129 views)
Re: [turnerr] Ftp directory listing not working with paths containing spaces [In reply to] Can't Post


Quote
I have a script that syncs up directory structures using ftp


That's a very inefficient approach. It would be far better and easier to use the proper tool for this task and that is rsync.

How are you initially calling the script? In particular, what is the exact path you pass in the -r option?

How are you initially calling the scan_ftp() sub?

I'm going to lunch but will post an updated test when I get back.


turnerr
Novice

Jan 2, 2014, 12:27 PM

Post #9 of 18 (2120 views)
Re: [FishMonger] Ftp directory listing not working with paths containing spaces [In reply to] Can't Post

The -r and -l parameters are:
/usr2/prod/app/oracle/Oraas/j2ee/act_webdev/applications/act_webdev/act_webdev/WEB-INF/classes/act/payment


FishMonger
Veteran / Moderator

Jan 2, 2014, 12:37 PM

Post #10 of 18 (2119 views)
Re: [turnerr] Ftp directory listing not working with paths containing spaces [In reply to] Can't Post

The ftp server that I'm testing on puts me into a change root jail which restricts me to my home directory. From there I created a directory tree where each dirname has at lease 1 space. Then I put 2 files into each sub dir.

The directory structure is as follows.

Code
[root@ftpserver ~]# ll -R 
.:
total 186960
drwxr-xr-x 3 root root 4096 Jan 2 09:45 New folder
-rw-r--r-- 1 root root 95617432 Dec 27 06:50 u00000952_2013122415_usd_gcsv3.csv
-rw-r--r-- 1 root root 95612049 Dec 27 06:50 u00000952_2013122418_usd_gcsv3.csv

./New folder:
total 186932
drwxr-xr-x 3 root root 4096 Jan 2 09:43 sub dir
-rw-r--r-- 1 root root 95599819 Dec 27 06:50 u00000952_2013122421_usd_gcsv3.csv
-rw-r--r-- 1 root root 95602518 Dec 27 06:50 u00000952_2013122500_usd_gcsv3.csv

./New folder/sub dir:
total 186944
drwxr-xr-x 2 root root 4096 Jan 2 09:43 another dir with spaces
-rw-r--r-- 1 root root 95597911 Dec 27 06:42 u00000952_2013122403_usd_gcsv3.csv
-rw-r--r-- 1 root root 95614427 Dec 27 06:48 u00000952_2013122406_usd_gcsv3.csv

./New folder/sub dir/another dir with spaces:
total 187008
-rw-r--r-- 1 root root 95628571 Dec 27 06:49 u00000952_2013122409_usd_gcsv3.csv
-rw-r--r-- 1 root root 95661954 Dec 27 06:50 u00000952_2013122412_usd_gcsv3.csv


I run the script from my Windows system and for the -r option I pass the relative or absolute path to the desired top level directory where script needs to start it processing. Keep in mind that the root dir / is in reality my home dir /home/perlmaster.

example: -r "/New folder/sub dir"

Since the script does a chdir (via $ftp->cwd($opt_r)), I pass '.' to the sub for the path. If the chdir was not done, then you'd need to pass $opt_r to the sub.

Inside the sub you don't need to worry about escaping the spaces in the path.

Here is the output I get when passing "/" for the -r option

Code
c:\test>turnerr.pl -s ftpserver -u perlmaster -p password -v 1 -o 0 -r "/" 
connected
path .
$VAR1 = [
'drwxr-xr-x 3 root root 4096 Jan 2 17:45 New folder',
'-rw-r--r-- 1 root root 95617432 Dec 27 14:50 u00000952_2013122415_usd_gcsv3.csv',
'-rw-r--r-- 1 root root 95612049 Dec 27 14:50 u00000952_2013122418_usd_gcsv3.csv'
];
after return
1 drwxr-xr-x 3 root root 4096 Jan 2 17:45 New folder
path ./New folder
$VAR1 = [
'drwxr-xr-x 3 root root 4096 Jan 2 17:43 sub dir',
'-rw-r--r-- 1 root root 95599819 Dec 27 14:50 u00000952_2013122421_usd_gcsv3.csv',
'-rw-r--r-- 1 root root 95602518 Dec 27 14:50 u00000952_2013122500_usd_gcsv3.csv'
];
after return
1 drwxr-xr-x 3 root root 4096 Jan 2 17:43 sub dir
path ./New folder/sub dir
$VAR1 = [
'drwxr-xr-x 2 root root 4096 Jan 2 17:43 another dir with spaces',
'-rw-r--r-- 1 root root 95597911 Dec 27 14:42 u00000952_2013122403_usd_gcsv3.csv',
'-rw-r--r-- 1 root root 95614427 Dec 27 14:48 u00000952_2013122406_usd_gcsv3.csv'
];
after return
1 drwxr-xr-x 2 root root 4096 Jan 2 17:43 another dir with spaces
path ./New folder/sub dir/another dir with spaces
$VAR1 = [
'-rw-r--r-- 1 root root 95628571 Dec 27 14:49 u00000952_2013122409_usd_gcsv3.csv',
'-rw-r--r-- 1 root root 95661954 Dec 27 14:50 u00000952_2013122412_usd_gcsv3.csv'
];
after return
1 -rw-r--r-- 1 root root 95628571 Dec 27 14:49 u00000952_2013122409_usd_gcsv3.csv
1 -rw-r--r-- 1 root root 95661954 Dec 27 14:50 u00000952_2013122412_usd_gcsv3.csv
1 -rw-r--r-- 1 root root 95597911 Dec 27 14:42 u00000952_2013122403_usd_gcsv3.csv
1 -rw-r--r-- 1 root root 95614427 Dec 27 14:48 u00000952_2013122406_usd_gcsv3.csv
1 -rw-r--r-- 1 root root 95599819 Dec 27 14:50 u00000952_2013122421_usd_gcsv3.csv
1 -rw-r--r-- 1 root root 95602518 Dec 27 14:50 u00000952_2013122500_usd_gcsv3.csv
1 -rw-r--r-- 1 root root 95617432 Dec 27 14:50 u00000952_2013122415_usd_gcsv3.csv
1 -rw-r--r-- 1 root root 95612049 Dec 27 14:50 u00000952_2013122418_usd_gcsv3.csv


Here is the test script with a few style fixes. There are additional coding style issues I was going to fix, but didn't want to rewrite the entire subroutine.


Code
#!/usr/bin/perl 

use strict;
use warnings;
use Net::FTP;
use Getopt::Std;
use Data::Dumper;

our ($opt_s, $opt_d, $opt_P, $opt_r, $opt_u, $opt_p, $opt_i, $opt_o, $opt_v);

getopt('sdPrupiov');

my $ftp = Net::FTP->new(
$opt_s,
Debug => $opt_d,
Passive => $opt_P,
) or die "Failed to connect to server '$opt_s': $@\n";


$ftp->login($opt_u, $opt_p) or die "Failed to login as $opt_u\n";
$ftp->cwd($opt_r) or die "Cannot change directory to $opt_r\n";
$ftp->binary() or warn "Failed to set binary mode\n";

print "connected\n" if $opt_v;

scan_ftp($ftp, '.');

sub scan_ftp {
my $ftp = shift;
my $path = shift;
my $rrem = shift;

print "path $path\n";

my $rdir = length($path) ? $ftp->dir($path) : $ftp->dir();
print Dumper $rdir;

return unless $rdir and @$rdir;
print "after return\n";

for my $f (@$rdir) {
print "1 $f\n";
next if $f =~ m/^d.+\s\.\.?$/;

my $n = ( split( /\s+/, $f, 9 ) )[8];
next unless defined $n;

my $name = '';
$name = $path . '/' if $path;
$name .= $n;

if ( $opt_i and $name =~ m/$opt_i/ ) {
print "ftp: IGNORING $name\n" if $opt_d;
next;
}

next if exists $rrem->{$name};

my $mdtm = ( $ftp->mdtm($name) || 0 ) + $opt_o;
my $size = $ftp->size($name) || 0;
my $type = substr( $f, 0, 1 );
$type =~ s/-/f/;

warn "ftp: adding $name ($mdtm, $size, $type)\n" if $opt_d;

$rrem->{$name} = {
mdtm => $mdtm,
size => $size,
type => $type,
};

scan_ftp( $ftp, $name, $rrem ) if $type eq 'd';
}
}



turnerr
Novice

Jan 2, 2014, 1:11 PM

Post #11 of 18 (2114 views)
Re: [FishMonger] Ftp directory listing not working with paths containing spaces [In reply to] Can't Post

Still not working for me. I copied you sub into my script but still get the same results. Here's the output

Code
Net::FTP>>> Net::FTP(2.72) 
Net::FTP>>> Exporter(5.58)
Net::FTP>>> Net::Cmd(2.24)
Net::FTP>>> IO::Socket::INET(1.27)
Net::FTP>>> IO::Socket(1.28)
Net::FTP>>> IO::Handle(1.24)
Net::FTP=GLOB(0x31384)<<< 220 ponos FTP server ready.
Net::FTP=GLOB(0x31384)>>> user oracle^M
Net::FTP=GLOB(0x31384)<<< 331 Password required for oracle.
Net::FTP=GLOB(0x31384)>>> PASS ....
Net::FTP=GLOB(0x31384)<<< 230 User oracle logged in.
Net::FTP=GLOB(0x31384)>>> CWD /usr2/prod/app/oracle/Oraas/j2ee/act_webdev/applications/act_webdev/act_webdev/WEB-INF/classes/act/payment^M
Net::FTP=GLOB(0x31384)<<< 250 CWD command successful.
Net::FTP=GLOB(0x31384)>>> TYPE I^M
Net::FTP=GLOB(0x31384)<<< 200 Type set to I.
connected
path
Net::FTP=GLOB(0x31384)>>> PORT 192,168,7,233,200,54^M
Net::FTP=GLOB(0x31384)<<< 200 PORT command successful.
Net::FTP=GLOB(0x31384)>>> LIST^M
Net::FTP=GLOB(0x31384)<<< 150 Opening BINARY mode data connection for /bin/ls.
Net::FTP=GLOB(0x31384)<<< 226 Transfer complete.
$VAR1 = [
'total 24',
'-rwxr----- 1 oracle oinstall 8965 Nov 15 10:29 Payment.class',
'-rwxr----- 1 oracle oinstall 1070 Nov 12 13:59 PaymentAccount.class',
'drwxr----- 3 oracle oinstall 512 Jan 1 09:11 cart'
];
after return
1 total 24
1 -rwxr----- 1 oracle oinstall 8965 Nov 15 10:29 Payment.class
Net::FTP=GLOB(0x31384)>>> MDTM Payment.class^M
Net::FTP=GLOB(0x31384)<<< 213 20131115162943
Net::FTP=GLOB(0x31384)>>> HELP SIZE^M
Net::FTP=GLOB(0x31384)<<< 214 Syntax: SIZE <sp> path-name
Net::FTP=GLOB(0x31384)>>> SIZE Payment.class^M
Net::FTP=GLOB(0x31384)<<< 213 8965
.
.
.
ftp: adding PaymentAccount.class (1384286359, 1070, f)
1 drwxr----- 3 oracle oinstall 512 Jan 1 09:11 cart
Net::FTP=GLOB(0x31384)>>> MDTM cart^M
Net::FTP=GLOB(0x31384)<<< 550 cart: not a plain file.
Net::FTP=GLOB(0x31384)>>> SIZE cart^M
Net::FTP=GLOB(0x31384)<<< 550 cart: not a plain file.
ftp: adding cart (0, 0, d)
path cart
Net::FTP=GLOB(0x31384)>>> PORT 192,168,7,233,200,55^M
Net::FTP=GLOB(0x31384)<<< 200 PORT command successful.
Net::FTP=GLOB(0x31384)>>> LIST cart^M
Net::FTP=GLOB(0x31384)<<< 150 Opening BINARY mode data connection for /bin/ls.
Net::FTP=GLOB(0x31384)<<< 226 Transfer complete.
$VAR1 = [
'total 38',
'drwxr----- 3 oracle oinstall 512 Jan 2 11:34 New folder',
'-rwxr----- 1 oracle oinstall 3129 Dec 3 2012 ShoppingCart.class',
'-rwxr----- 1 oracle oinstall 3393 Jun 18 2013 ShoppingCartAccount.class',
'-rwxr----- 1 oracle oinstall 8491 Jun 18 2013 ShoppingCartAccountInformation.class',
'-rw-r----- 1 oracle oinstall 686 Jan 1 09:12 tst'
];
after return
1 total 38
1 drwxr----- 3 oracle oinstall 512 Jan 2 11:34 New folder
Net::FTP=GLOB(0x31384)>>> MDTM cart/New folder^M
Net::FTP=GLOB(0x31384)<<< 550 cart/New folder: not a plain file.
Net::FTP=GLOB(0x31384)>>> SIZE cart/New folder^M
Net::FTP=GLOB(0x31384)<<< 550 cart/New folder: not a plain file.
ftp: adding cart/New folder (0, 0, d)
path cart/New folder
Net::FTP=GLOB(0x31384)>>> PORT 192,168,7,233,200,56^M
Net::FTP=GLOB(0x31384)<<< 200 PORT command successful.
Net::FTP=GLOB(0x31384)>>> LIST cart/New folder^M
Net::FTP=GLOB(0x31384)<<< 150 Opening BINARY mode data connection for /bin/ls.
Net::FTP=GLOB(0x31384)<<< 226 Transfer complete.
$VAR1 = [];
1 -rwxr----- 1 oracle oinstall 3129 Dec 3 2012 ShoppingCart.class
Net::FTP=GLOB(0x31384)>>> MDTM cart/ShoppingCart.class^M
Net::FTP=GLOB(0x31384)<<< 213 20121203182147
Net::FTP=GLOB(0x31384)>>> SIZE cart/ShoppingCart.class^M
Net::FTP=GLOB(0x31384)<<< 213 3129
ftp: adding cart/ShoppingCart.class (1354558907, 3129, f)
[\code]
.
.
Here's the code I'm using:

Code
. 

my $ftp = Net::FTP->new(
$opt_s,
Debug => $opt_d,
Passive => $opt_P,
) or die "Failed to connect to server '$opt_s': $@\n";


$ftp->login($opt_u, $opt_p) or die "Failed to login as $opt_u\n";
$ftp->cwd($opt_r) or die "Cannot change directory to $opt_r\n";
$ftp->binary() or warn "Failed to set binary mode\n";

print "connected\n" if $opt_v;

##scan_ftp($ftp, '.');

sub scan_ftp {
my $ftp = shift;
my $path = shift;
my $rrem = shift;

print "path $path\n";

my $rdir = length($path) ? $ftp->dir($path) : $ftp->dir();
print Dumper $rdir;

return unless $rdir and @$rdir;
print "after return\n";

for my $f (@$rdir) {
print "1 $f\n";
next if $f =~ m/^d.+\s\.\.?$/;

my $n = ( split( /\s+/, $f, 9 ) )[8];
next unless defined $n;

my $name = '';
$name = $path . '/' if $path;
$name .= $n;

if ( $opt_i and $name =~ m/$opt_i/ ) {
print "ftp: IGNORING $name\n" if $opt_d;
next;
}
next if exists $rrem->{$name};

my $mdtm = ( $ftp->mdtm($name) || 0 ) + $opt_o;
my $size = $ftp->size($name) || 0;
my $type = substr( $f, 0, 1 );
$type =~ s/-/f/;

warn "ftp: adding $name ($mdtm, $size, $type)\n" if $opt_d;

$rrem->{$name} = {
mdtm => $mdtm,
size => $size,
type => $type,
};

scan_ftp( $ftp, $name, $rrem ) if $type eq 'd';
}
}

scan_ftp($ftp, '', \%rem);

.
It's still not listing the cart/New folder directory.
Thanks.


FishMonger
Veteran / Moderator

Jan 2, 2014, 1:33 PM

Post #12 of 18 (2111 views)
Re: [turnerr] Ftp directory listing not working with paths containing spaces [In reply to] Can't Post

That's odd.

It's possible, but maybe unlikely, that it's due to a bug in the older version of Net::FTP that you're using. Try upgrading to the newer version (which is 2.78) and see if that clears it up.

I'm tied up on one of my projects, so it'll be a while before I can do more testing on my side.


turnerr
Novice

Jan 2, 2014, 2:26 PM

Post #13 of 18 (2106 views)
Re: [FishMonger] Ftp directory listing not working with paths containing spaces [In reply to] Can't Post

Upgraded to 2.78 and still get the same results. The only other difference I noticed is that you're on windows and my systems are solaris.


FishMonger
Veteran / Moderator

Jan 2, 2014, 2:45 PM

Post #14 of 18 (2103 views)
Re: [turnerr] Ftp directory listing not working with paths containing spaces [In reply to] Can't Post

I just tested from my CentOS box and it was successful.


Code
[root@099-91-RKB-2 ~]# ./turnerr.pl -s ftpserver -u fishmonger -p password -v 1 -o 0 -r "/New folder" 
connected
path .
after return
1 drwxr-xr-x 3 root root 4096 Jan 2 17:43 sub dir
path ./sub dir
after return
1 drwxr-xr-x 2 root root 4096 Jan 2 17:43 another dir with spaces
path ./sub dir/another dir with spaces
after return
1 -rw-r--r-- 1 root root 95628571 Dec 27 14:49 u00000952_2013122409_usd_gcsv3.csv
1 -rw-r--r-- 1 root root 95661954 Dec 27 14:50 u00000952_2013122412_usd_gcsv3.csv
1 -rw-r--r-- 1 root root 95597911 Dec 27 14:42 u00000952_2013122403_usd_gcsv3.csv
1 -rw-r--r-- 1 root root 95614427 Dec 27 14:48 u00000952_2013122406_usd_gcsv3.csv
1 -rw-r--r-- 1 root root 95599819 Dec 27 14:50 u00000952_2013122421_usd_gcsv3.csv
1 -rw-r--r-- 1 root root 95602518 Dec 27 14:50 u00000952_2013122500_usd_gcsv3.csv



turnerr
Novice

Jan 2, 2014, 3:14 PM

Post #15 of 18 (2098 views)
Re: [FishMonger] Ftp directory listing not working with paths containing spaces [In reply to] Can't Post

Is your ftpserver windows? It appears that it may be a problem with the ftp on the server. I tried a command line ftp to my server and receive the same results as I'm getting with my perl script.
.

Code
ftp> dir 
200 PORT command successful.
150 Opening ASCII mode data connection for /bin/ls.
total 24
-rwxr----- 1 oracle oinstall 8965 Nov 15 10:29 Payment.class
-rwxr----- 1 oracle oinstall 1070 Nov 12 13:59 PaymentAccount.class
drwxr----- 3 oracle oinstall 512 Jan 1 09:11 cart
226 Transfer complete.
215 bytes received in 0.00044 seconds (480.73 Kbytes/s)
ftp> dir cart
200 PORT command successful.
150 Opening ASCII mode data connection for /bin/ls.
total 38
drwxr----- 3 oracle oinstall 512 Jan 2 11:34 New folder
-rwxr----- 1 oracle oinstall 3129 Dec 3 2012 ShoppingCart.class
-rwxr----- 1 oracle oinstall 3393 Jun 18 2013 ShoppingCartAccount.class
-rwxr----- 1 oracle oinstall 8491 Jun 18 2013 ShoppingCartAccountInformation.class
-rw-r----- 1 oracle oinstall 686 Jan 1 09:12 tst
226 Transfer complete.
remote: cart
382 bytes received in 0.00023 seconds (1588.56 Kbytes/s)
ftp> dir cart/New folder
200 PORT command successful.
150 Opening ASCII mode data connection for /bin/ls.
226 Transfer complete.
ftp> dir cart/New\ folder
200 PORT command successful.
150 Opening ASCII mode data connection for /bin/ls.
226 Transfer complete.
ftp> dir 'cart/New folder'
200 PORT command successful.
150 Opening ASCII mode data connection for /bin/ls.
226 Transfer complete.
ftp> dir "cart/New folder"
200 PORT command successful.
150 Opening ASCII mode data connection for /bin/ls.
226 Transfer complete.
ftp>
.



FishMonger
Veteran / Moderator

Jan 3, 2014, 6:13 AM

Post #16 of 18 (2078 views)
Re: [turnerr] Ftp directory listing not working with paths containing spaces [In reply to] Can't Post

I just ran a new test and was able to duplicate your issue. The answer is obvious and I should have seen of it earlier, but I made the mistake of making an assumption.

Check the permissions of the dirs and files. The user account that is used to connect via ftp needs to have read rights on the files and possibly execute bit set on the dirs. So, in your case based on the dir listing that you posted, that user needs to be oracle or oinstall. If you're logging in with a different account then it falls under 'other' which doesn't have proper rights.


(This post was edited by FishMonger on Jan 3, 2014, 6:15 AM)


turnerr
Novice

Jan 3, 2014, 12:02 PM

Post #17 of 18 (2061 views)
Re: [FishMonger] Ftp directory listing not working with paths containing spaces [In reply to] Can't Post

I am logging in with oracle.


FishMonger
Veteran / Moderator

Jan 3, 2014, 12:10 PM

Post #18 of 18 (2058 views)
Re: [turnerr] Ftp directory listing not working with paths containing spaces [In reply to] Can't Post

In that case, I don't see any reason why it would be failing for you other than something weird going on with solaris.


(This post was edited by FishMonger on Jan 3, 2014, 12:13 PM)

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives