Error reason from Perl Net::FTP - perl

I'm using Net::FTP to transfer files up to a mainframe and I'm testing failure conditions.
My code is basically along the following lines:
my $ftp = Net::FTP->new ("mainframe.com", Timeout => 20);
if (! $ftp) {
logMessage ("Could not connect to host: $!");
return;
}
if (! $ftp->login ("paxdiablo", "demigodemporeroftheuniverse")) {
logMessage ("Could not log in to host: $!");
$ftp->quit ();
return;
}
if (! $ftp->put ("myfile.txt", "'CANT.WRITE.TO.THIS'")) {
logMessage ("Could not put file: $!");
$ftp->quit ();
return;
}
I know I can't create the data set CANT.WRITE.TO.THIS since I don't have the required permissions but, when I try, the only message I see is:
Could not put file:
There is no indication in $! as to what the problem was. I've looked in the Net::FTP doco and all it says is:
put ( LOCAL_FILE [, REMOTE_FILE ] )Put a file on the remote server. LOCAL_FILE may be a name or a filehandle. If LOCAL_FILE is a filehandle then REMOTE_FILE must be specified. If REMOTE_FILE is not specified then the file will be stored in the current directory with the same leafname as LOCAL_FILE.Returns REMOTE_FILE or the generated remote filename if REMOTE_FILE is not given.
I also cannot find anything there about retrieving the specific error (like $ftp->getLastError() or something similar).
How can I indicate to the user why the transfer failed?
On an earlier iteration, I resorted to putting the file, then getting it again and checking contents locally. I'd really rather not have to inflict such kludgy code on people again.

From Net::FTP:
$ftp = Net::FTP->new("some.host.name", Debug => 0)
or die "Cannot connect to some.host.name: $#"
Note $#.
$ftp->cwd("/pub")
or die "Cannot change working directory ", $ftp->message;
Note $ftp->message

Related

Read and compare images in folder using Perl

I am trying to read and compare large number of image files in a folder. But I am not able to read the image file.
Code snippet :
use strict;
use warnings;
use Image::Compare;
opendir my $ref_dir, "./" or die "Cannot open directory: $!";
my #ref_files = readdir $ref_dir;
closedir $ref_dir;
print $#ref_files;
my($cmp) = Image::Compare->new();
$cmp->set_image1(
img => './'.$ref_files[0], #one instance - reading first file in the folder
type => 'bmp',
);
The code is throwing the following error - "Unable to read image data from file './.': 'Could not open ./.: Permission denied' at C:/Perl64/site/lib/Image/Compare.pm line 162. "
The code works fine if I provide the file name directly - img => './image.bmp'. So it can't be a permission issue.
The error message seems pretty clear.
Unable to read image data from file './.': 'Could not open ./.: Permission denied
The first file you're getting back from opendir() is the current directory (.) - and it's no surprise that Image::Compare can't get the image data that it wants from that file!
Perhaps you should add a filter to only return the files you're interested in.
my #ref_files = grep { -f } readdir $ref_dir;

perl timeout when downloading file from ftp

I try to download huge file which takes a lot of time downloading from ftp link using perl.
I got:
Timeout at C:/Strawberry/perl/lib/Net/FTP.pm
what does this means and how to solve it?
Thanks
Solution:
Thanks #Chris Doyle
I change the timeout value in my perl file "not ftp.pm file"
Thanks
You can increase the timeout, but it is important that if the timeout is reached again and your server/client are out of sync, it might throw the same error you got the first time, again.
It seems that the issue is due a lack of error handling in your Perl Script instead.
Surely you have something like this at your perl script:
my $ftp = Net::FTP->new( $myhost, Timeout => 10, Debug => 1 );
...
$ftp->get($myfile) or print "Got an error";
$ftp->quit();
Please notice this is out of .../perl/lib/Net/FTP.pm, since the
FTP.pm is the third party module (Kind of library) you are using to
reach the ftp, I suggest you to not touch it to avoid portability
issues later on.
Normally the timeout is reached inside the FTP.pm and it goes to the or print "Got an error" condition, but there are some cases, that the Server/Client just get out of sync and the FTP.pm just throws an unhandled exception.
This exception will NOT go to the or print "Got an error" condition, therefore you need to catch it and handle it as any other languages.
Here you can use eval to wrap it up the code, catch the exception and handle it as you need.
For example:
my $ftp = Net::FTP->new( $myhost, Timeout => 10, Debug => 1 );
...
eval {$ftp->get($myfile) or print("Can't get file $myfile") };
if ($# =~ /Timeout/) {
print "Got a timeout Issue: $#";
}
$ftp->quit();

Download multiple files from SFTP using perl Net::SFTP::Foreign

I am using the below code to download files from SFTP and I am getting error message after one file download. Then I am rerunning the program and then it downloads only one file again and when trying to download the next file in the array it get failed. I couldn't understand the reasons for this failure and kindly review the below code and share opinions.
#!/usr/bin/perl
use strict;
use Net::SFTP::Foreign::Constants qw(:error :status);
use Net::SFTP::Foreign;
use Net::SFTP::Foreign::Attributes;
my $SFTP_CON=Net::SFTP::Foreign->new("sftpserver.test.com",user=>"testuser",password=>"pass");
my #SFTP_Files=('/test/1.txt','/test/2.txt','/test/3.txt');
my $root_dir='/test/';
$local_dir='/u/test/';
foreach my $file_to_dwn(#SFTP_Files){
my $file_to=$file_to_dwn;
$file_to=~s/$root_dir/$local_dir/igs;
unless($SFTP_CON->get("$file_to_dwn","$file_to")){
if (($SFTP_CON->error == SFTP_ERR_REMOTE_STAT_FAILED or
$SFTP_CON->error == SFTP_ERR_REMOTE_OPEN_FAILED) and
$SFTP_CON->status == SSH2_FX_NO_SUCH_FILE) {
print "Remote file does not exist!";
exit;
}
else {
print "Transfer Failed";
exit;
}
print $SFTP_CON->error."\n";
exit;
}
}
I am getting "Transfer Failed", when the program tries to download the one after another (second file download).
Please do needful.

perl error- Can't call method "domain" on an undefined value

#!/usr/bin/perl -w
use Net::SMTP;
$smtp = Net::SMTP->new('mailhost');
print $smtp->domain,"\n";
$smtp->quit;
I run this pl file and get error "Can't call method "domain" on an undefined value"
and in this pl file:
#!/usr/bin/perl -w
use Net::SMTP;
$smtp = Net::SMTP->new('mailhost');
$smtp->mail($ENV{USER});
$smtp->to('postmaster');
$smtp->data();
$smtp->datasend("To: postmaster\n");
$smtp->datasend("\n");
$smtp->datasend("A simple test message\n");
$smtp->dataend();
$smtp->quit;
I get error Can't call method "mail" on an undefined value
What I need todo ?
Has it occured to you that Net::SMTP may have had problems finding your mailhost, and establishing an SMTP connection? I see that you took your scripts directly from the documentation – you do have to supply an actual value for mailhost.
If you had read the documentation a bit further, especially to the documentation for the new method, you'd have found this interesting snippet:
new ( [ HOST ] [, OPTIONS ] )
This is the constructor for a new Net::SMTP object. HOST is the name of the remote host to which an SMTP connection is required.
On failure undef will be returned and $# will contain the reason for the failure.
So let's print out that reson for failure:
my $mailhost = "your mailhost";
my $smpt = Net::SMTP->new($mailhost) or die "Can't connect to $mailhost: $#";
die aborts your program with an error message. This message should tell you more about the actual error.
Do note that the example code in the documentation is not neccessarily meant to be used for real projects – it is just there to showcase the capabilities of the module. For real code, always use strict; use warnings at the top of your code, and declare all your variables with my. This helps finding more errors.

Undocumented iPhone APIs - Discovery and Use

There are a handful of iPhone apps out there doing some behind-the-scenes trickery with undocumented APIs, with effective results.
How would I go about getting a listing of undocumented iPhone APIs?
Are there third-party off-the-cuff documentation for some of these APIs?
You could use classdump to get a listing of the iPhone SDK, but I don't know about the (non)existence of third-party documentation. You could probably get an idea of what the methods do by reading their names, though.
Erica Sadun, one of the most well respected iPhone hackers has a book out on precisely this. Most of the undocumented header files can be pulled from her website too.
I've found a perl script(source= arstechnika), wich builds a folder of headers from the public and private frameworks of the iPhone SDK. However I get an error (class-dump failed, returning 16777215
), if i run it.
#!/usr/bin/perl
#
# 24 November 2008
# Framework Dumping utility; requires class-dump
#
use strict;
use Cwd;
use File::Path;
my $HOME = (getpwuid($<))[7] || $ENV{'HOME'}
or die "Could not find your home directory!";
# This command must be in your path.
# http://www.codethecode.com/projects/class-dump/
my $CLASS_DUMP = 'class-dump';
# Public Frameworks
dump_frameworks('/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator2.0.sdk/System/Library/Frameworks',
'Frameworks');
# Private Frameworks
dump_frameworks('/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator2.0.sdk/System/Library/PrivateFrameworks',
'PrivateFrameworks');
sub dump_frameworks
{
my($dir, $subdir) = #_;
opendir(my $dirh, $dir) or die "Could not opendir($dir) - $!";
# Iterate through each framework found in the directory
foreach my $file (grep { /\.framework$/ } readdir($dirh))
{
# Extract the framework name
(my $fname = $file) =~ s/\.framework$//;
print "Framework: $fname\n";
my $headers_dir = "$HOME/Headers/$subdir/$fname";
# Create the folder to store the headers
mkpath($headers_dir);
# Perform the class-dump
my $cwd = cwd();
chdir($headers_dir) or die "Could not chdir($headers_dir) - $!";
system($CLASS_DUMP, '-H', "$dir/$file");
if(my $ret = $? >> 8)
{
die "$CLASS_DUMP failed, returning $ret\n";
}
chdir($cwd) or die "Could not chdir($cwd) - $!";
}
}