Operating System - HP-UX
1828354 Members
3047 Online
109976 Solutions
New Discussion

perlscript encode a file to UTF-8 and send via ftp

 
SOLVED
Go to solution
'chris'
Super Advisor

perlscript encode a file to UTF-8 and send via ftp

hi

I've written a perl script to encode the file to UTF-8 and dend it via ftp , but it wont send any files.

I get following error message:
550 /var/data.txt: The system cannot find the path specified.

knows someone howto correct this code ?

#!/usr/bin/perl -w

use strict;
use warnings;

use Net::FTP;
use Net::Netrc;

use Encode qw/encode decode/;
use utf8;

my $server = "x.x.x.x";
my $user = "user";
my $password = "password";
my $file = "/var/data.txt";

my $ftp = Net::FTP->new ($server, Timeout => 9000, Debug => 3);
$ftp or die "$server: cannot connect: $@";
$ftp->login ($user,$password) or die "$_: Could not login: " . $ftp->message;
$ftp->cwd($destination);

#encoding and put file
open FILE, '<', $file or die "open $file $!";
binmode FILE, 'encoding(utf-8)' or die $!;

$ftp->put(\*FILE, $file); # must give remote name.

$ftp->quit;
12 REPLIES 12
H.Merijn Brand (procura
Honored Contributor
Solution

Re: perlscript encode a file to UTF-8 and send via ftp

Some small remarks that /might/ help.
- If you have a recent perl (perl-5.8.2 or up), there is no need for encode/decode. You already used the three-arg form of open, See 'man perlopentut' for the wider form of explanations. Theoretically, this should work as of 5.8.0, but a lot of bugs were solved in the releases that followed. 5.8.4 is the (currently) most recent.
- And -w and 'use warnings' both is doing it double. Better cautious that sorry probably :)
- If you use Net::Netrc, don't put the user and password in the script. ~/.netrc is enough
- Use $ftp->message instead of $@
- Don't forget $ftp->binary. Even though you *KNOW* that the ftp server will give binary by default, it's good practice to request that anyway (the might change server as I found out not too long ago on a mac)

--8<---
#!/usr/bin/perl

use strict;
use warnings;

use Net::FTP;
use Net::Netrc;

my $server = "x.x.x.x";
my $file = "/var/data.txt";

my $ftp = Net::FTP->new ($server, Timeout => 9000, Debug => 3) or die "$server: cannot connect: ".$ftp->message;
$ftp->login or die "login: " .$ftp->message;
$ftp->binary or die "binary: ".$ftp->message;
$ftp->cwd ($destination) or die "cd $destination: ".$ftp->message;

open my $fh, "<:utf8", $file or die "open $file: $!";
$ftp->put ($fh, $file); # must give remote name.
close $fh or die "Cannot close file\n";
$ftp->quit;
-->8---

I admire your safe programming style. I only made the file handle lexical too. And I closed the file handle and checked for error.

Enjoy, Have FUN! H.Merijn
Enjoy, Have FUN! H.Merijn
'chris'
Super Advisor

Re: perlscript encode a file to UTF-8 and send via ftp

thanks !
I've tried your code, but it wont transfer the file and still get this message like before:

Net::FTP=GLOB(0x83df0c0)<<< 220 ttn208 Microsoft FTP Service (Version 5.0).
Net::FTP=GLOB(0x83df0c0)>>> user user
Net::FTP=GLOB(0x83df0c0)<<< 331 Password required for user.
Net::FTP=GLOB(0x83df0c0)>>> PASS ....
Net::FTP=GLOB(0x83df0c0)<<< 230 User user logged in.
Net::FTP=GLOB(0x83df0c0)>>> TYPE I
Net::FTP=GLOB(0x83df0c0)<<< 200 Type set to I.
Net::FTP=GLOB(0x83df0c0)>>> CWD /tmp
Net::FTP=GLOB(0x83df0c0)<<< 250 CWD command successful.
Net::FTP=GLOB(0x83df0c0)>>> PORT 192,168,0,1,143,9
Net::FTP=GLOB(0x83df0c0)<<< 200 PORT command successful.
Net::FTP=GLOB(0x83df0c0)>>> STOR /var/data.txt
Net::FTP=GLOB(0x83df0c0)<<< 550 /var/data.txt: The system cannot find the path specified.
Net::FTP=GLOB(0x83df0c0)>>> QUIT
Net::FTP=GLOB(0x83df0c0)<<< 221

I think the problem is because it looks for /var/data.txt on the remote server, but this is a local path.
remote path is /tmp and there the file should
be transfered.
do you know, how can I solve this problem ?

greetings
chris
H.Merijn Brand (procura
Honored Contributor

Re: perlscript encode a file to UTF-8 and send via ftp

That does not look as how the docs say it should work.

What's your version of perl?

# perl -v

And what's your version of Net::FTP?

# perl -MNet::FTP -le'print $Net::FTP::VERSION"

I'd like to check myself.
FWIW currently I have:

lt09:/home/merijn 101 > perl -v

This is perl, v5.8.3 built for i686-linux-64int
(with 1 registered patch, see perl -V for more detail)

Copyright 1987-2003, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using `man perl' or `perldoc perl'. If you have access to the
Internet, point your browser at http://www.perl.com/, the Perl Home Page.

lt09:/home/merijn 102 > perl -MNet::FTP -le'print $Net::FTP::VERSION'
2.74
lt09:/home/merijn 103 > perl -MV=Net::FTP
Net::FTP
/pro/lib/perl5/5.8.3/Net/FTP.pm: 2.74
lt09:/home/merijn 104 >

Change 331 on 1999/09/18 by (Graham Barr)

Net::FTP
- get and put now accept *FD as well as \*FD for the local filehandle

So the method you are using is allowed for at least since Sep 1999.


Having said all of this, I just think of the most obvious: Di you strip the path from the file?

$file =~ s{.*/}{};
$ftp->put ($fh, $file);

Should probably fix your problem.

Enjoy, Have FUN! H.Merijn [ wondering why he thought about themost obvious only after looking for the least obvious ... ]
Enjoy, Have FUN! H.Merijn
Procnus
Frequent Advisor

Re: perlscript encode a file to UTF-8 and send via ftp

I've hit similar problems in the past, now I change to the source directory, either by a cd before the ftp or with a lcd within the ftp, and just PUT the filename with no path.

Steven
'chris'
Super Advisor

Re: perlscript encode a file to UTF-8 and send via ftp

hi Procura

thanks a lot, now it works well !

# perl -v
This is perl, v5.8.0 built for i586-linux-thread-multi

# perl -MNet::FTP -le'print $Net::FTP::VERSION'
2.65

but I'll update both of them shortly.

greetings
chris
'chris'
Super Advisor

Re: perlscript encode a file to UTF-8 and send via ftp

hi Procura

I've updatet perl to 5.8.3 and
I should transfer these file in ASCII mode.
there are CSV (text) files, I get from AS400 and should send to the mickysoft machine.

if I change to:

$ftp->ascii or die "ascii: ".$ftp->message;

or put away this line, then I get this error message:

Net::FTP=GLOB(0x830c7d8)<<< 220 ttn208 Microsoft FTP Service (Version 5.0).
Net::FTP=GLOB(0x830c7d8)>>> user user
Net::FTP=GLOB(0x830c7d8)<<< 331 Password required for user.
Net::FTP=GLOB(0x830c7d8)>>> PASS ....
Net::FTP=GLOB(0x830c7d8)<<< 230 User user logged in.
Net::FTP=GLOB(0x830c7d8)>>> CWD /tmp
Net::FTP=GLOB(0x830c7d8)<<< 250 CWD command successful.
Net::FTP=GLOB(0x830c7d8)>>> ALLO 27844
Net::FTP=GLOB(0x830c7d8)<<< 200 ALLO command successful.
Net::FTP=GLOB(0x830c7d8)>>> PORT 192,168,0,1,128,56
Net::FTP=GLOB(0x830c7d8)<<< 200 PORT command successful.
Net::FTP=GLOB(0x830c7d8)>>> STOR data.txt
Net::FTP=GLOB(0x830c7d8)<<< 150 Opening ASCII mode data connection for data.txt
Wide character in syswrite at /usr/lib/perl5/5.8.3/Net/FTP/A.pm line 92.

do you know what could be wrong ?
H.Merijn Brand (procura
Honored Contributor

Re: perlscript encode a file to UTF-8 and send via ftp

1. It's just a warning
2. I /think/ yopu should go for binary transfer anyway. If you need CR/LF conversions, do it in the script
3. We (on the perl front) don't realy know if FTP (the server part, in your case on M$) is defined well enough to support UTF-8 at all. Maybe by sending it binary, you can prevent that message

Enjoy, Have FUN! H.Merijn
Enjoy, Have FUN! H.Merijn
'chris'
Super Advisor

Re: perlscript encode a file to UTF-8 and send via ftp

hi Procura

thanks, it works, but with UTF-8 I still get problems.
I've found out today, that the remote machine doesn't support UTF8, but it supports UTF-16.

do you know how to change to UTF16 ?

should I install an additional modul ?

greetings
chris
H.Merijn Brand (procura
Honored Contributor

Re: perlscript encode a file to UTF-8 and send via ftp

Since UTF-8 is a subset of UTF-16, I would expect it to "Just Work As Expected" (TM)
But OTOH, it's M$, so it probably won't.
We had some discussions about the utf8-ness of the ftp output file handle on perl5-porters, and I don't know if any consensus was reached after I went to bed.
Fact is that none of us knew how to explicitly set utf8-ness to the output socket, and at what stage perl has no more control over it.
A workaround at the moment seems to be my suggestion to use Compress::ZIP to create a Windows zip file, and ftp that in plain uncoded binary, and use unpzip/winzip/power-archiver on the target side to unzip it.

Enjoy, Have FUN! H.Merijn [ who spent some time in Net::FTP's internals only to find out it's a pretty dark forrest out there of inheritance trees ]
Enjoy, Have FUN! H.Merijn
'chris'
Super Advisor

Re: perlscript encode a file to UTF-8 and send via ftp

hi

I cannot use the zip or tar solution in my case, otherwise the file cannot be processed on the remote site.

if I convert from shell with:

# iconv -f latin1 -t UTF16 test.txt > test1.txt

and send test1.txt ascii via ftp it looks fine for some tests.

but don't know how to do with perl.

greetings
chris
H.Merijn Brand (procura
Honored Contributor

Re: perlscript encode a file to UTF-8 and send via ftp

fast way out:

open my $fh, "iconv -f latin1 -t UTF16 test.txt |" or die ".....";

I bet use Encode can help here too, but I never used that.

Enjoy, Have FUN! H.Merijn
Enjoy, Have FUN! H.Merijn
'chris'
Super Advisor

Re: perlscript encode a file to UTF-8 and send via ftp

thanks a lot, Procura !

do you think, can I use Mod "Unicode" as well ?

greetings
chris