use strict; use warnings; use constant error => -1; use constant noerror => 0; use constant false => 0; use constant true => 1; $| = true; # # Modules Used # use Data::Dumper; use File::Basename; use File::ReadBackwards ; use File::Tail; use Win32::GUI(); use Win32::GuiTest qw(:ALL); # # Who am I? # my $MyName = (fileparse($0, '\..*'))[0]; # # Globals # my $LogFilesTail = undef(); # # ReadTails # # Read Latest File Updates from File::Tailed files # # Arguments: \@TailedLogFiles # # Returns: undef if something went awry, otherwise $TailedLines # $TailedLines = # [ # { # 'File1' => # [ # 'Line1' # , 'Line2' # . # . # . # , 'LineN' # ] # # } # ]; # sub ReadTails { my($TailedLogFiles) = shift; my $TimeOut = 5; my $TailedLines = undef(); my $Found = true; while (true) { my @Pending; ($Found, undef, @Pending) = File::Tail::select(undef, undef, undef, $TimeOut, @$TailedLogFiles); if($Found) { foreach (@Pending) { # print $_->{"input"}." (".localtime(time).") ".$_->read; # print(__FILE__ . '(' . __LINE__ . ')' . "\[$_->{buffer}\]\n"); push(@{$TailedLines->{$_->input}}, $_->{buffer}); } last(); } } return($TailedLines); } # # FindNewestlog # # Find Newest Putty Log File # # Arguments: $PuttyLogDirectory # # Returns: error if something went awry, otherwise $PuttyLogFileName # sub FindNewestlog { my($PuttyLogDir) = shift; my $DirH; opendir($DirH, $PuttyLogDir) or return(undef()); my @Files = readdir($DirH); closedir($DirH); my $NewestFile; $NewestFile->{'Name'} = undef(); $NewestFile->{'Date'} = 0; foreach my $File (@Files) { if((-d $File)) { next(); } elsif($File =~ /\d+\-.*\.log/) { my $CreateDate = (stat(($PuttyLogDir . $File)))[10]; if($CreateDate > $NewestFile->{'Date'}) { $NewestFile->{'Name'} = $PuttyLogDir . $File; $NewestFile->{'Date'} = $CreateDate; } else { next(); } } else { next(); } } return($NewestFile->{'Name'}); } # # Minus # # Subtract Two Arrays # # Arguments: $Array1 # $Array2 # # Returns: error if something went awry, otherwise $Difference # sub Minus { my($Array1, $Array2) = @_; # "Subtract" (remove) elements of @minus from @list: # Thanks to PerlMonks tye & princepawn my %dup; @dup{@$Array2}= (); my @list = @$Array1; @list = grep { not exists $dup{$_} } @list; return(\@list); } # # StartPutty # # Start a Putty Session and Return the Window Handle # # Arguments: $SessionName - Putty Session Name # $UnixId - Unix user name # $UnixPassword - Unix Password # $UnixPrompt - Command line Prompt # $PuttyLogDirectory - Local Directory Where the Putty Logs Can be Found # $LogFileTailArray - Array of Tail File Handles # # Returns: error if something went awry, otherwise $PuttyInfo # sub StartPutty { my($SessionName, $UnixId, $UnixPassword, $UnixPrompt, $PuttyLogDirectory, $LogFileTailArray) = @_; # # Start a New Putty Window # my $PuttyInfo; my @WindowsBefore = FindWindowLike(undef, $SessionName); print(__FILE__ . '(' . __LINE__ . ')' . "Starting Putty Session:\[$SessionName\]\n"); system("start \"$SessionName\" \"C:\\Program Files\\PuTTY\\putty.exe\" -load \"$SessionName\" -l f17mg0 -pw \"$UnixPassword\""); sleep(3); my @WindowsAfter = FindWindowLike(undef, $SessionName); my $Difference = Minus(\@WindowsAfter, \@WindowsBefore); # # Find the New Putty Window # if(scalar(@$Difference) == 1) { # # Get the New Putty Window's Handle # print(__FILE__ . '(' . __LINE__ . ')' . "Getting Putty Window Handle\n"); $PuttyInfo->{'WindowHandle'} = $Difference->[0]; my $SavedActiveWindow = GetActiveWindow($PuttyInfo->{'WindowHandle'}); # # Get Putty Log File Name # $PuttyInfo->{'LogFileName'} = FindNewestlog($PuttyLogDirectory); print(__FILE__ . '(' . __LINE__ . ')' . "\$PuttyInfo->{'LogFileName'}:\[$PuttyInfo->{'LogFileName'}\]\n"); if(defined($PuttyInfo->{'LogFileName'})) { # # Start Tailing log File # my $LogFileTail = File::Tail->new ( 'name' => $PuttyInfo->{'LogFileName'} ); print(__FILE__ . '(' . __LINE__ . ')' . "Log File Tail Received...\n"); if($LogFileTail) { $PuttyInfo->{'Tail Handle'} = $LogFileTail; push(@$LogFileTailArray, $PuttyInfo->{'Tail Handle'}); while(1) { print(__FILE__ . '(' . __LINE__ . ')' . "Reading Log File...\n"); my $TailData = ReadTails($LogFileTailArray); if(grep(/$UnixPrompt/, @{$TailData->{$PuttyInfo->{'LogFileName'}}})) { print(__FILE__ . '(' . __LINE__ . ')' . "Found:\[$UnixPrompt\].\n"); last(); } else { print(__FILE__ . '(' . __LINE__ . ')' . "\[$UnixPrompt\] Not Found\n"); } } # # sudo to admin id # SetActiveWindow($PuttyInfo->{'WindowHandle'}); SendKeys("exec sudo su - $UnixId~"); sleep(1); SendKeys($UnixPassword . '~'); sleep(1); SendKeys('. ./p~'); SetActiveWindow($SavedActiveWindow); } else { $PuttyInfo = undef(); } } else { $PuttyInfo = undef(); } } else { $PuttyInfo = undef(); } return($PuttyInfo); } # # StopPutty # # Stop a Putty Session # # Arguments: $PuttyInfo - Putty Session Hash Ref # # Returns: Nothing worth getting bothered about # sub StopPutty { my ($PuttyInfo) = shift; my $SavedActiveWindow = GetActiveWindow($PuttyInfo->{'WindowHandle'}); SetActiveWindow($PuttyInfo->{'WindowHandle'}); SendKeys('exit~'); SetActiveWindow($SavedActiveWindow); } # # Main # my $UnixId = 'MyId'; my $UnixPassword = 'MyPW'; my $UnixPrompt = '@SystemName'; my $SessionName = 'System Name'; my $PuttyLogDirectory = "C:\\Log\\"; my $PuttyOldLogDirectory = "C:\\Log\\Old"; my $TailedPuttyLogs; my $PuttyInfo = StartPutty($SessionName, $UnixId, $UnixPassword, $UnixPrompt, $PuttyLogDirectory, $TailedPuttyLogs); print(__FILE__ . '(' . __LINE__ . ')' . "Active Window:\[$PuttyInfo->{'WindowHandle'}\] PuttyLogFileName:\[$PuttyInfo->{'LogFileName'}\]\n"); WMSetText($PuttyInfo->{'WindowHandle'},"Test Primary"); SetActiveWindow($PuttyInfo->{'WindowHandle'}); my @WindowCorners = GetWindowRect($PuttyInfo->{'WindowHandle'}); # print("\@WindowCorners:\[" . (Dumper(\@WindowCorners)) . "\]\n"); my ($ScrWidth, $ScrHeight) = GetScreenRes(); print(__FILE__ . '(' . __LINE__ . ')' . "\$ScrWidth:\[$ScrWidth\] \$ScrHeight:\[$ScrHeight\]\n"); bless($PuttyInfo->{'WindowHandle'}, 'Win32::GUI'); $PuttyInfo->{'WindowHandle'}->Resize(($ScrWidth * .5), $ScrHeight); StopPutty($PuttyInfo); __END__