#!/usr/bin/perl use strict; use warnings; use IO::Pty (); use Data::Dumper; use Net::Telnet (); use Config::IniFiles; use Fcntl qw(:flock); $| = 1; my $path = "conf.ini"; my $command = "sudo ntpdate ntp.ubuntu.com"; sub devices { open my $fh , '<' , "".$path."" or die "Could not open file: ".$path." - $!\n"; flock($fh, LOCK_SH) or die "Could not lock '".$fh."' - $!\n"; tie my %ini, 'Config::IniFiles', ( -file => "".$path."" ) or die "Error: IniFiles->new: @Config::IniFiles::errors"; close ($fh) or die "Could not close '".$fh."' - $!\n"; print Dumper(\%ini); my @keys = keys (%ini); my @data; my @loop; foreach my $hash (@keys) { @loop = clk_sync( $ini{$hash}{IP}, $ini{$hash}{user}, $ini{$hash}{psw}, $ini{$hash}{prompt}, $ini{$hash}{port}, $ini{$hash}{dump_log}, $ini{$hash}{input_log} ); push(@data,@loop); } print Dumper(\@data); return @data; } # end sub complex my @list = devices(); sub spawn { my (@cmd) = @_; my ($pid, $pty, $tty, $tty_fd); ## Create a new pseudo terminal. $pty = new IO::Pty or die $!; ## Execute the program in another process. unless ($pid = fork) { # child process die "problem spawning program: $!\n" unless defined $pid; ## Disassociate process from its controlling terminal. use POSIX (); POSIX::setsid() or die "setsid failed: $!"; ## Associate process with a new controlling terminal. $pty->make_slave_controlling_terminal; $tty = $pty->slave; $tty_fd = $tty->fileno; close $pty; ## Make standard I/O use the new controlling terminal. open STDIN, "<&$tty_fd" or die $!; open STDOUT, ">&$tty_fd" or die $!; open STDERR, ">&STDOUT" or die $!; close $tty; ## Execute requested program. exec @cmd or die "problem executing $cmd[0]\n"; } # end child process $pty; } # end sub spawn sub clk_sync { my $host = shift; my $user = shift; my $passwd = shift; my $prompt = shift; my $port = shift; my $dump_log = shift; my $input_log = shift; my ($buf, $match, $pty, $ssh, @lines); ## Start ssh program. $pty = spawn("ssh", "-l", $user, "-p", $port, "-e", "none", "-F", "/dev/null", "-o", "PreferredAuthentications=password", "-o", "NumberOfPasswordPrompts=1", "-o", "StrictHostKeyChecking=no", "-o", "UserKnownHostsFile=/dev/null", $host); ## Create a Net::Telnet object to perform I/O on ssh's tty. $ssh = new Net::Telnet (-fhopen => $pty, -prompt => $prompt, -telnetmode => 0, -dump_log => $dump_log, -input_log => $input_log, -timeout => 20, -output_record_separator => "\r", -cmd_remove_mode => 1); ## Wait for the password prompt and send password. $ssh->waitfor(-match => '/password: ?$/i', -errmode => "return") or die "problem connecting to \"$host\": ", $ssh->lastline; $ssh->print($passwd); ## Wait for the shell prompt. (undef, $match) = $ssh->waitfor(-match => $ssh->prompt, -match => '/^Permission denied/m', -errmode => "return") or return $ssh->error("login failed: expected shell prompt ", "doesn't match actual\n"); return $ssh->error("login failed: bad login-name or password\n") if $match =~ /^Permission denied/m; ## Run commands on remote host. #@lines = $ssh->cmd("hostname"); @lines = $ssh->cmd("sudo ntpdate ntp.ubuntu.com"); #@lines = $ssh->cmd("uptime"); $ssh->close; return @lines; } __END__ $VAR1 = { 'Device 1' => { 'IP' => 'IP', 'user' => 'USER', 'psw' => 'PASSWORD', 'prompt' => '/[\\$%#>] $/', 'port' => 'PORT', 'hostname' => 'ubuntu' }, 'Device 2' => { 'IP' => 'IP', 'user' => 'USER', 'psw' => 'PASSWORD', 'prompt' => '/[\\$%#>] $/', 'port' => 'PORT', 'hostname' => 'ubuntu' } }; $VAR1 = [ ' 04:23:41 up 4:25, 3 users, load average: 0.12, 0.30, 0.42 ', 'Operating:~', ' 04:23:42 up 4:25, 3 users, load average: 0.12, 0.30, 0.42 ', 'Operating:~' ];