# # $Header: rfeOpenFile.pl 24-jun-2007.22:17:18 rtakeish Exp $ # # rfeOpenFile.pl # # Copyright (c) 2005, 2007, Oracle. All rights reserved. # # NAME # rfeOpenFile.pl - Perl script to get file contents for Remote File Editor Page # in Edit and View Modes # # DESCRIPTION # # # NOTES # # # MODIFIED (MM/DD/YY) # rtakeish 06/12/07 - bug5041899, multibyte file contents not supported # sreddy 01/24/06 - a # sreddy 01/23/06 - fix bug#4968435 # sreddy 01/18/06 - fix bug#4955527 # sreddy 01/18/06 - XbranchMerge sreddy_bug-4955527 from # st_emagent_10.2.0.1.1 # ajere 12/07/05 - For Windows OS, call this script with commonenv.bat context # ajere 07/28/05 - Fix bug# 4503778 # ajere 06/27/05 - ajere_bug-4386234_1 # ajere 06/27/05 - Creation require "emd_common.pl"; use strict; use hostGenFunctions; #Subroutine declarations sub openFile($); sub performPreFileOpenChk($$$$); sub checkWritePermission($$); #Global variables my $windowsOsCmd = "cmd"; my $unixOsCmd = "/bin/sh"; ############################################# # openFile() # Subroutine to get file contents ############################################# sub openFile($) { #Input params my $osCmd = $ARGV[0]; my $fileName = $ARGV[1]; my $fileSizeLimitKB = $ARGV[2]; my $rfeViewMode = $ARGV[3]; my $preOpenChkMsg = "NULL"; my $preOpenChkError = "FALSE"; my $fileContents = ""; #If the file name is null, return if (!$fileName) { EMD_PERL_ERROR("[rfeFilerViewer.pl] Input file name is empty!\n"); exit 1; } #For Windows OS, execute exec_commonenv.bat if mount_shares.bat #and unmount_shares.bat files exist if (($osCmd eq $windowsOsCmd) && !defined($ENV{EM_AGENT_COMMONENV_BAT_EXEC}) && (-e "$ENV{EMDROOT}/bin/mount_shares.bat") && (-e "$ENV{EMDROOT}/bin/unmount_shares.bat")) { #save STDERR into STDERZR_ORIG. Upon failure, skip exec_commonenv.bat step if (open (STDERR_ORIG, ">&STDERR")) { #send STDERR to null device. Upon failure, skip exec_commonenv.bat step if (open (STDERR, ">/dev/null")) { my $beginToken="BEGIN_REMOTE_OP_RESULT_SET_AFTER_COMMONENV_BAT"; my $endToken="END_REMOTE_OP_RESULT_SET_AFTER_COMMONENV_BAT"; my $beginTokenFound=0; my $line; #Batch file exec_commonenv.bat sets EM_AGENT_COMMONENV_BAT_EXEC and #call this script again after network shares from mount_shares.bat #are mounted. This block won't get executed then and the array #scriptResult will contain actual output within start and end tokens. my @scriptResult=`$ENV{EMDROOT}\\bin\\exec_commonenv.bat rfeOpenFile.pl @ARGV`; #restore STDERR to STDERR_ORIG close(STDERR); open (STDERR, ">&STDERR_ORIG") or EMD_PERL_ERROR("rfeOpenFile.pl: Failed to restore STDERR"); #Note: There is no good reason why the above open will fail. Upon #failure, there is no need to exit since result will be sent #on STDOUT back to OMS #Extract actual output of this script chomp @scriptResult; foreach $line (@scriptResult) { if ($line =~ $endToken) { print "$`"; #prints the content on last line #if it does not end with exit 0; } print "$line\n" if ($beginTokenFound eq 1); $beginTokenFound=1 if ($line =~ $beginToken); } exit 0; } else { EMD_PERL_ERROR("rfeOpenFile.pl: Failed to redirect STDERR to null device"); } } else { EMD_PERL_ERROR("rfeOpenFile.pl: Failed to save STDERR into STDERR_ORIG"); } } #Default fileSizeLimitKB is 100 KB if(!$fileSizeLimitKB || !($fileSizeLimitKB =~ /\d/)) { $fileSizeLimitKB = 100; } #print "fileSizeLimitKB = $fileSizeLimitKB\n"; #Perform pre-open file checks ($preOpenChkMsg, $preOpenChkError) = performPreFileOpenChk($osCmd, $fileName, $fileSizeLimitKB, $rfeViewMode); #Get the file contents, iff pre-open checks indicate file can be opened if(($preOpenChkMsg ne "FILE_DOESNT_EXIST")&&($preOpenChkError eq "FALSE")) { #Open the file if (!open(FH, "$fileName")) { EMD_PERL_ERROR("[rfeFilerViewer.pl] Unable to open the file $fileName for reading!\n"); exit 1; } #Go to EOF seek(FH,0,2); #Get the file size and start point my $fileSize = (-s $fileName); my $startPoint = $fileSize - $fileSizeLimitKB*1000; if($startPoint < 0) { $startPoint = 0; } #print "startPoint = $startPoint\n"; #Seek to the start point if(!seek(FH, $startPoint, 0)) { EMD_PERL_ERROR("[rfeFilerViewer.pl] Unable to seek to the start point of the file $fileName!\n"); exit 1; } #Get file contents in chunks my $bufferSizeBytes = 1000; my $line; while(read(FH, $line, $bufferSizeBytes)) { $fileContents.= $line; } #Full contents not read! if($startPoint ne 0) { $preOpenChkMsg = "RFE_SHOWING_PARTIAL_CONTENTS_VIEW_MODE"; } #Close the file close FH; } return $preOpenChkMsg."|".$preOpenChkError."\n"."$fileContents"; } ############################################# # performPreFileOpenChk() # Subroutine to Perform pre-open file checks ############################################# sub performPreFileOpenChk($$$$) { my $osCmd = $_[0]; my $fileName = $_[1]; my $fileSizeLimitKB = $_[2]; my $rfeViewMode = $_[3]; my $directory = $fileName; #Pre-open check logic #File is a directory file! return ("FILE_IS_DIRECTORY", "TRUE") if(-d $fileName); #Get the parent directory if ($osCmd eq $windowsOsCmd) { #Windows if($fileName =~ /(.*\\)/) { $directory = $1; } } elsif ($osCmd eq $unixOsCmd) { #UNIX if ($fileName =~ m!(.*\/)!) { $directory = $1; } } #print ("directory = $directory\n"); #File doesn't exist if (!-e $fileName) { #Edit Mode if($rfeViewMode eq "FALSE") { #Parent directory has write permissions if (-d $directory && -w $directory) { my $writePermission=1; $writePermission = checkWritePermission($fileName, $osCmd); return ("FILE_DOESNT_EXIST", "FALSE") if ($writePermission); } #Parent directory doesn't have write permissions! return ("NO_CREATE_PERMISSIONS", "TRUE"); } else { return ("FILE_DOESNT_EXIST_VIEW_MODE", "TRUE"); } } else { #No read permissions! if (!-r $fileName) { return ("CANT_ACCESS_FILE", "TRUE"); } #Not a text file! if (!-T $fileName) { #Perl limitation workaround - bug# 4503778, bug# 5041899 #For UNIX OS and Windows OS, re-check whether it's really a non-text file if(!hostGenFunctions::isTextFile($fileName, $osCmd)) { return ("NON_EDITABLE_FILE_CONTENTS", "TRUE"); } } #Edit Mode if($rfeViewMode eq "FALSE") { #File is greater than maximum limit! if (($fileSizeLimitKB =~ /\d/) && ((-s $fileName) > $fileSizeLimitKB*1000)) { return ("FILE_TOO_BIG", "TRUE"); } my $writePermission = checkWritePermission($fileName, $osCmd); return ("NO_WRITE_PERMISSIONS", "FALSE") if (!$writePermission); } } #No message & no errors return ("NULL", "FALSE"); } ########################################################### # checkWritePerssion() # Subroutine to test if it is possible to write to the file ########################################################### sub checkWritePermission($$) { my $fname = shift @_; my $osCmd = shift @_; my $writePermission = 0; if ($osCmd eq $unixOsCmd) { $writePermission = 1 if ((! -e $fname) || (-w $fname)); } elsif ($osCmd eq $windowsOsCmd) { # # On Windows, if (-w $fname) test sometimes returns true # value even if the file is not writeable. This can happen # on a directory where the user is not granted FULL # privileges. This subroutine verifies the write permission # by opening the file in append mode. It cleans up the # file if it did not exist before the file was opened # in append mode. # # This is one of the issues fixed as part of bug#4968435 # my $removeFile = 0; $removeFile = 1 if ( ! -e $fname ); if (open(TEST_FH,">>$fname")) { $writePermission=1; close(TEST_FH); unlink($fname) if ($removeFile); } } return $writePermission; } #For Windows OS only if ($ARGV[0] eq $windowsOsCmd && defined($ENV{EM_AGENT_COMMONENV_BAT_EXEC})) { my $openFileRes = openFile(@ARGV); print "$openFileRes"; exit 0; } return 1;