Perl script to download a file from LAN - perl

path is similar to this \\pc1\folder1\folder2\file.bin
Above is the shared folder on the network
and I have to save it to a path similar to c:\Users\me\Desktop\file_copy.bin
I am new to Perl and thus clear explanation of how it is happening will be appreciable.

You can try the Win32::FileOp module, below is how you open the file, you can use the CopyFile option for downloading.
use Win32::FileOp qw/ Map /;
Map 'X:' => ' \\\\machine\\share',
{ user => 'foo', passwd => 'bar' };
open FILE, 'x:/path/file.ext' or die "...";
Also check out File::Fetch

Related

How do I force extraction to fail if the destination directory doesn't exist?

I’m using Perl 5.16.3 with Archive::Extract
I am extracting a zip file, but I would like Perl to fail (die) if the destination directory doesn’t exist. Currently the below code does not fail, but creates the directory before extraction takes place
use Archive::Extract;
...
my $ae = Archive::Extract->new( archive => $downloadedFile, type => 'zip' );
my $ok = $ae->extract( to => $deployDir ) or die $ae->error;
How can I force things to die if the destination directory doesn’t exist?
There's nothing in the module that allows you to disable the automatic creation of the directory, so you just check it in a separate statement prior to the extract call
-d $deployDir or die {Deployment directory "$deployDir" doesn't exist};
Or you could use autodie and try to open it as a directory. That way the system will generate a die message for you. Like this
{
use autodie;
opendir my ($dh), $deployDir;
}
This requires Perl v5.10.1 or later. The braces { ... } around the code are required. They limit the scope of autodie and automatically close the directory handle again immediately

Perl sFTP : how to check remote file doesnt exist

I am 1 day old to Perl, was going through API doc here, have few basic questions
$sftp = Net::SFTP::Foreign->new($host, autodie => 1);
my $ls = $sftp->ls("/bar");
# dies as: "Couldn't open remote dir '/bar': No such file"
Question
with autodie will the connection be auto closed ?
we see in above example how to use folder , similar syntax also works for file ?
Or something like this makes more sense ??
my $sftp = Net::SFTP::Foreign->new($host, autodie => 1);
$sftp->find("/sdfjkalshfl", # nonexistent directory
on_error => sub { print "foo!\n";sftp->disconnect();exit; });
I was trying to run following code on my windows machine
use Net::SFTP::Foreign;
my $host = "demo.wftpserver.com";
my $sftp = Net::SFTP::Foreign->new($host ,ssh_cmd => 'plink',autodie => 1);
my $ls = $sftp->ls("/bar");
But i get error
'plink' is not recognized as an internal or external command ,
however when i run plink from windows command line it works fine !!
with autodie will the connection be auto closed ?
Yes. When the program ends, everything is destroyed and connections are closed. That is also the case when the $sftp variable goes out of scope. Modules like this usually implement a DESTROY sub. Those are invoked when the object (which is just a reference in Perl) goes out of scope. There can be some cleanup in that sub. Another example that has that is DBI, and of course lexical filehandles (like $fh from a open call).
we see in above example how to use folder , similar syntax also works for file ?
No. The docs say ls is for a directory:
Fetches a listing of the remote directory $remote. If $remote is not given, the current remote working directory is listed.
But you can just do ls for the directory that the file you want is in, and use the wanted option.
my $ls = $sftp->ls( '/home/foo', wanted => qr/^filename.txt$/ );
Though with the autodie that should die, so if you don't want it to actually die here, you should wrap it in a Try::Tiny call or an eval.
use Try::Tiny
# ...
my $ls = try {
return $sftp->ls( '/home/foo', wanted => qr/^filename.txt$/ );
} catch {
return; # will return undef
};
say 'Found file "filename.txt" on remote server' if $ls;
As to plink being not found, probably the Windows PATH is different from what your Perl sees.

How to create zip file in perl?

Hi friends i can create a zip file using files which is there in the directory where the script is currently running now i want to create zip file from various directory can anybody help me?
my code is;
use IO::Compress::Zip qw(:all);
zip [ glob("inventory_report_for_neus.xls") ] => "my.zip"
or die "Cannot create zip file: $ZipError" ;
this will produce zip file with specific files but
use IO::Compress::Zip qw(:all);
zip [ glob("..\\inventory_report_for_neus.xls") ] => "my.zip"
or die "Cannot create zip file: $ZipError" ;
this is also produce zip file but there is no file inside!
Updated
IO::Compress::Zip creates a zip file with a hierarchical structure based on the original locations of the files within the current directory.
However, a result of this is that it does not correctly handle files that are not enclosed by the current working directory.
The simplest solution is probably to change directories to the parent directory before zipping. If that is not an option, copy the files to a temporary location before zipping, or possibly use IO::Compress::Zip's more advanced features, like writing the zip file from a filehandle.
friends finally i found solution for this case..simply i've used shell command inside perl so i'll create zip file with appropriate files...code as follows.
use strict;
use warnings;
use MIME::Lite;
use Net::SMTP;
my $msg = MIME::Lite->new (
From => 'xyz#gmail.com',
To => 'thiyagu040#gmail.com',
Subject => 'with inline images',
Type =>'multipart/mixed'
) or die "Error creating mult;$!\n";
system("zip test.zip '../test_dir/report.xls'");
.
.
.
.
$msg ->( filename => test.zip,
content_type => 'application/zip',
disposition => 'attachment',
name => $filename,
);
MIME::Lite->send('smtp', 'smtp.gmail.com', Timeout=>60,AuthUser=>'xyz', AuthPass=>'remotecontrol');
$msg->send();

Problems using the HTML::Template module

I'm unable to execute the HTML::Template function in the CGI.
I'm following a simple tutorial that I found here: http://metacpan.org/pod/HTML::Template
I created a new file on my server in the home path as test.tmpl.
I created a new file named frt.cgi ... (is that the issue here? should it be a different file extention??)
#!/usr/local/bin/perl -w
use HTML::Template;
# open the html template
my $template = HTML::Template->new(filename => '/test.html');
# fill in some parameters
$template->param(HOME => $ENV{HOME});
$template->param(PATH => $ENV{PATH});
# send the obligatory Content-Type and print the template output
print "Content-Type: text/html\n\n", $template->output;
I've modified the 1st line to reflect my host provided program path for perl. I don't know what the -w does I just know I've tried this with and without it. Also I've tried changing the code a bit like this:
use warnings;
use strict;
use CGI qw(:standard);
use HTML::Template;
I've searched...
https://stackoverflow.com/search?q=HTML%3A%3ATEMPLATE+&submit=search
https://stackoverflow.com/search?q=HTML%3A%3ATEMPLATE
https://stackoverflow.com/search?q=HTML%3A%3ATEMPLATE+PERL&submit=search
Yet I still do not see the answer.
I even searched google for .TMPL Encoding because I thought there may be some special type needed. Please help.
If you look in your server logs, you'll probably see an error message along the lines of:
HTML::Template->new() : Cannot open included file /test.html : file not found.
You need to provide the path on the file system, not a URI relative to the generated document.
First, you likely specified the wrong path - change /test.html to test.html.
Also, it is possible that there is no $ENV{HOME} variable in your system so set up flag die_on_bad_params to 0:
my $template = HTML::Template->new(
filename => 'test.html',
die_on_bad_params => 0,
);
Also, don't forget to mark your Perl file as executable by chmod 755.
Option -w makes Perl to enable warnings, so there is no point to write use warnings; afterwards.
You can check what Perl command line options do by using module B::Deparse, like this ($^W variable disables/enables warnings):
perl -w -MO=Deparse -e "print;"
This would print:
BEGIN { $^W = 1; }
print $_;

In Perl, how do I get the directory or path of the current executing code?

If I am in some library code, how do I determine the path to the file of the code that is currently executing? I know how to get the path of the top perl file by looking at ARGV, but if I load a library, how can that library know which path it is at?
The __FILE__ token will give you the full path including the file name. You can use File::Spec to split it into components:
my ($volume, $directory, $file) = File::Spec->splitpath(__FILE__);
The easiest way to find the filename of the current executable is with FindBin:
use FindBin;
use File::Spec;
print "the directory of my script is: " . $FindBin::Bin . "\n";
print "the base name of my script is: " . $FindBin::Script . "\n";
print "the canonical location of my script is: " . File::Spec->catfile($FindBin::Bin, $FindBin::Script) . "\n";
Internally, you can get at some of this information by looking at $0 (the name of the script as invoked at the command line), and __FILE__, which is the name of the currently-executing file. (See perldoc perlvar.)
To extract the filename of the currently-executing module, start with examining __PACKAGE__, do some substitution magic and then look up the filename in %INC:
(my $filename = __PACKAGE__ ) =~ s#::#/#g;
$filename .= '.pm';
my $abs_filename = $INC{$filename};
I do this in one of my initialization libraries to find a configuration script in a path relative to the current module (I have several code branches installed side-by-side, each with slightly different configs):
# use the location of the current module as a guide for where to find configs
(my $filename = __PACKAGE__ ) =~ s#::#/#g;
$filename .= '.pm';
(my $path = $INC{$filename}) =~ s#/\Q$filename\E$##g; # strip / and filename
my $abs_config_file = File::Spec->catfile($path, $config_file);
MyApp->initialize($abs_config_file);
Any libraries included via use or require produce an entry in the special %INC hash. (See perlvar).
For example:
use strict;
use warnings;
use Data::Dumper;
print Dumper \%INC;
This will produce output similar to the following:
$VAR1 = {
'warnings/register.pm' => '/usr/lib/perl5/5.8.8/warnings/register.pm',
'bytes.pm' => '/usr/lib/perl5/5.8.8/bytes.pm',
'XSLoader.pm' => '/usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi/XSLoader.pm',
'Carp.pm' => '/usr/lib/perl5/5.8.8/Carp.pm',
'Exporter.pm' => '/usr/lib/perl5/5.8.8/Exporter.pm',
'strict.pm' => '/usr/lib/perl5/5.8.8/strict.pm',
'warnings.pm' => '/usr/lib/perl5/5.8.8/warnings.pm',
'overload.pm' => '/usr/lib/perl5/5.8.8/overload.pm',
'Data/Dumper.pm' => '/usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi/Data/Dumper.pm'
};
Additionally, there is a universal __FILE__ constant which will return the current filename. (See also __PACKAGE__).
This is the snippet I usually use to get the path for the executing code.
use Cwd qw/abs_path/;
my ($real_path) = abs_path($0) =~ m/(.*)myscript.pl/i;
This puts the actual directory path into $real_path. I usually also perform chdir $real_path after this to make sure my code is actually working out of the directory it should be (usually when I'm writing a Windows service using Win32::Daemon).
The abs_path subroutine I've exported gives the path to whatever file (name/handle) you supply as the argument. In this case I've supplied $0 which is the name of the Perl script being executed.
I would recommend checking out Cwd on Cpan for a little more guidance.
Easiest way:
print $ENV{'PWD'};