Why doesn't my program work? It refuses to connect to the host, I've tried two different servers and verified which port is used.
Note that I'm not very experienced when it comes to Perl.
use strict;
use Net::FTP;
use warnings;
my $num_args = $#ARGV+1;
my $filename;
my $port;
my $host;
my $ftp;
if($num_args < 2)
{
print "Usage: ftp.pl host [port] file\n";
exit();
}
elsif($num_args == 3)
{
$port = $ARGV[1];
$host = $ARGV[0];
$filename = $ARGV[2];
print "Connecting to $host on port $port.\n";
$ftp = Net::FTP->new($host, Port => $port, Timeout => 30, Debug => 1)
or die "Can't open $host on port $port.\n";
}
else
{
$host = $ARGV[0];
$filename = $ARGV[1];
print "Connecting to $host with the default port.\n";
$ftp = Net::FTP->new($host, Timeout => 30, Debug => 1)
or die "Can't open $host on port $port.\n";
}
print "Usename: ";
my $username = <>;
print "\nPassword: ";
my $password = <>;
$ftp->login($username, $password);
$ftp->put($filename) or die "Can't upload $filename.\n";
print "Done!\n";
$ftp->quit;
Thanks in advance.
Now that you already have your answer <> -> <STDIN>, I think I see the problem. When #ARGV contains anything, <> is the 'magic open'. Perl interprets the next item in #ARGV as a filename, opens it and reads it line by line. Therefore, I think you can probably do something like:
use strict;
use Net::FTP;
use warnings;
use Scalar::Util 'looks_like_number';
if(#ARGV < 2)
{
print "Usage: ftp.pl host [port] file [credentials file]\n";
exit();
}
my $host = shift; # or equiv shift #ARGV;
my $port = (looks_like_number $ARGV[0]) ? shift : 0;
my $filename = shift;
my #ftp_args = (
$host,
Timeout => 30,
Debug => 1
);
if ($port)
}
print "Connecting to $host on port $port.\n";
push #ftp_args, (Port => $port);
}
else
{
print "Connecting to $host with the default port.\n";
}
my $ftp = Net::FTP->new(#ftp_args)
or die "Can't open $host on port $port.\n";
#now if #ARGV is empty reads STDIN, if not opens file named in current $ARGV[0]
print "Usename: ";
chomp(my $username = <>); #reads line 1 of file
print "\nPassword: ";
chomp(my $password = <>); #reads line 2 of file
$ftp->login($username, $password);
$ftp->put($filename) or die "Can't upload $filename.\n";
print "Done!\n";
$ftp->quit;
Then if you had some connection creditials in a file (say named cred) like
myname
mypass
then
$ ftp.pl host 8020 file cred
would open host:8020 for file using credentials in cred.
I'm not sure you want to do that, its just that THAT is how <> works.
Related
I do no understand why my script below hangs and is timed out on transfer of a very small file. If someone can assist whether it is a problem of configuration, or whatever.
#!/usr/bin/perl
use strict;
use warnings;
use Net::FTP;
my $host = "server";
my $user = "username";
my $pass = "password";
#!!!!!!!!!!!!!!!!!!!!!!!!!!
my $ftp = Net::FTP->new($host, passive => 1, time => 360, Debug => 1) or die "Error connecting to $host: $!\n";
$ftp->login($user, $pass) or die "Cannot login to $user: $!\n";
$ftp->ascii();
#!!!!!!!!!!!!!!!!!!!!!!!!!!
opendir(my $DIR, "./") or die $!;
my #files=readdir($DIR);
foreach my $file (#files){
next if -d $file;
next unless $file =~/^OBS_ZB/;
for my $file(glob 'OBS_ZB*'){
eval{$ftp->put($file, $file) or print("Can't send file $file\n")};
if($# =~ /Timeout/){
print "Got a timeout Issue: $#";
}
}
}
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
print "copying ends\n";
exit 0;
my $file = 'log.log';
my $cmd = 'sysstat';
my $ssh = Net::SSH::Perl->new($host);
$ssh->login('admin', 'password');
open my $in, "-|", ($ssh->cmd($cmd))[0];
open my $out_fh, ">", $file;
#print+($ssh->cmd($cmd))[0]."\n";
while (my $line = <$in>) {
print { $out_fh } $line;
}
Any recommendations for how to log ssh output to a file in real time? $cmd will run forever and I'd like each line it spits out be written to the file in real time.
You can't do that with Net::SSH::Perl... well, at least not easily!
Use Net::OpenSSH instead:
$ssh = Net::OpenSSH->new($host, user => $user, password => $password);
$ssh->system({stdout_file => $file}, $cmd);
I am trying to create a remote-login script with perl. I am currently getting input data using
$var = <$client>;
chomp $var;
However, I am trying to have the client input a password and I want to hide the password in the linux fashion with the client by not echoing what is typed. Is there any way I can do this?
EDIT:
$serv = IO::Socket::INET->new (
Proto => 'tcp',
LocalPort => $port,
Listen => 10,
Reuse => 1)
|| die "Can't create server: $!";
while ($client = $serv->accept()) {
eval {
$client->autoflush(1); # Always remember to flush!
$who = $client->peerhost;
print STDERR "Connection from $who\n";
print $client hostname . " login: ";
$usr = <$client>;
chomp $usr;
$usr =~ s/\W//g;
print STDERR "User $usr\n";
die unless (length $usr < 20 && length $usr > 1);
print $client "Encrypted Password: ";
$pass = <$client>;
chomp $pass;
die unless (length $pass < 20 && length $pass > 1);
print STDERR "$who: Pass $pass\n";
};
close $client;
}
This is local console echo, nothing to do with your socket.
There are many ways to turn off console echo using Perl, but my favourite is IO::Termios (perhaps I'm biased because I wrote it ;) )
use IO::Termios;
my $stdin = IO::Termios->new(\*STDIN);
$stdin->setflag_echo(0);
I currently have some code which returns a sites header content back:
#!/usr/bin/perl
use strict;
require IO::Socket;
my #header;
my $host = shift;
my $socket = new IO::Socket::INET(
PeerAddr => $host,
PeerPort => 80,
Proto => 'tcp') || die "Could not Connect $!\n";
print "Connected.\n";
print "Getting Header\n";
print $socket "GET / HTTP/1.0\n\n";
my $i = 0;
while (<$socket>) {
#header[$i] = $_;
$i++;
}
$i = 0;
print "--------------------------------------\n";
while ($i <= 8) {
print "#header[$i++]";
}
print "-------------------------------------\n";
print "Finished $host\n";
What I would like to do, is to be able to read from a file open (FILE, '<', shift); and then every IP in the file, to pass into a the header retrieve loop, which saves me from manually doing one by one.
What I mean by this is to have a file containing (example ips): 1.1.1.1 2.2.2.2 on each line and then parsing all of them through the get header function.
Replace
my #header;
my $host = shift;
...
with
while (<>) {
chomp( my $host = $_ );
my #header;
...
}
You would just open your file, read the contents into a list, then iterate over the list:
open my $fh, '<', $file or die "$!";
my #ips = <$fh>;
close $fh;
foreach my $ip ( #ips ) {
chomp $ip;
...
}
Error:
Syntax error: end of file unexpected
Below is the Code
I changed.
"#!/usr/local/bin/perl"
The actual program is
#!/local/perl5/bin/perl5.003
use Socket;
$sockaddr = 'S n a4 x8';
$host = $ARGV[0];
$them = $host;
$port = 79;
print "Finger $host: \n";
$hostname = ``;
`nslookup $host |grep Name: >> $test`;
print $test;
#($name, $aliases, $proto) = getprotobyname('tcp');
($name, $aliases, $port) = getservbyname($port, 'tcp') unless $port =~ /^\d+$/;
($name, $aliases, $type, $len, $thisaddr) = gethostbyname($hostname);
$n1 = $name;
($name, $aliases, $type, $len, $thataddr) = gethostbyname($them);
$this = pack($sockaddr, &AF_INET, 0, $thisaddr);
$that = pack($sockaddr, &AF_INET, $port, $thataddr);
socket(S, &PF_INET, &SOCK_STREAM, $proto) || die "socket: $!";
bind(S, $this) || die "bind: $!";
connect(S, $that);
select(S); $| = 1; select(stdout);
print S "\n\n";
while (<S>) {print $_;};
Here:
`nslookup $host |grep Name: >> $test`;
$test is undefined at that point, so you're asking the shell to execute nslookup whatever.com |grep Name: >>. Where is the shell supposed to redirect the output to?
If you set $test to be something, like a filename.. or even $test = "$host.txt"; it will get you further.
Nothing to do with your Perl version, although being able to use strict;use warnings does help, as it would've caught the above error.