Created
July 20, 2020 12:40
-
-
Save plavjanik/219ba63fe5881e718a2ef449e2c43e65 to your computer and use it in GitHub Desktop.
setup2.pl
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #! /usr/bin/env perl | |
| use File::Basename; | |
| use Cwd 'abs_path'; | |
| use lib dirname($0).'/oebin'; | |
| use CheckHeldOutput; | |
| use Getopt::Long; | |
| use Pod::Usage; | |
| use File::Basename; | |
| my ($uninstall, $help) = (); | |
| GetOptions ( | |
| "uninstall" => \$uninstall, | |
| "help|?" => \$help, | |
| ) or pod2usage(2); | |
| pod2usage(1) if ($help); | |
| my $user=uc($ENV{'LOGNAME'}?$ENV{'LOGNAME'}:uc(`id -un`)); | |
| chomp $user; | |
| my $jclJobName=(length($user)>7?$user:"${user}A"); | |
| my $BYTES_PER_CYLINDER=696000; | |
| my $rplRoot="___REPLACE_ROOT___"; | |
| my $usrHLQ=uc($ENV{'COMPILER_INSTALL_HLQ'}?$ENV{'COMPILER_INSTALL_HLQ'}:"${user}.NJSV12B"); | |
| my $leHLQ=uc($ENV{'LE_INSTALL_HLQ'}?$ENV{'LE_INSTALL_HLQ'}:"CEE"); | |
| my $rteHLQ=uc($ENV{'RTE_INSTALL_HLQ'}?$ENV{'RTE_INSTALL_HLQ'}:"CBC"); | |
| my $msgCLS=uc($ENV{'COMPILER_INSTALL_HELD_MSGCLASS'}?$ENV{'COMPILER_INSTALL_HELD_MSGCLASS'}:'S'); | |
| my $jclVol=($ENV{'COMPILER_INSTALL_VOLSER'}?" VOLUME($ENV{'COMPILER_INSTALL_VOLSER'})":()); | |
| my $accinfo=($ENV{'ACCOUNTING_INFO'}?$ENV{'ACCOUNTING_INFO'}:'157A,2326'); | |
| my $rplHLQ="___REPLACE_HLQ___"; | |
| my $rplLEHLQ="___REPLACE_LE_HLQ___"; | |
| my $rplRTEHLQ="___REPLACE_RTE_HLQ___"; | |
| my $sqfHLQ="USRHLQ"; | |
| my $instroot=abs_path(dirname($0)); | |
| my $ussRoot="$instroot/uss.images"; | |
| my $tgtRoot="$instroot/bin"; | |
| my @files=(); | |
| my @listOfDatasets=(); | |
| if (&isUninstall) { | |
| die "<ERR> failed to uninstall because target path $tgtRoot does not exist, please make sure to run ". | |
| "this script under the same directory where unpack.pl was previously run during installation" | |
| if (!-d $tgtRoot); | |
| } else { | |
| # Prereq check | |
| my $hasDependenciesInstalled=1; | |
| if (! -d "/usr/include/le" ) { | |
| print "WARNING: Dependency \"/usr/include/le\" not found\n"; | |
| $hasDependenciesInstalled=0; | |
| } | |
| if (! -f "/usr/lpp/cbclib/lib/libibmcmp.a" ) { | |
| print "WARNING: Dependency \"/usr/lpp/cbclib/lib/libibmcmp.a\" not found\n"; | |
| $hasDependenciesInstalled=0; | |
| } | |
| if (!$hasDependenciesInstalled) { | |
| print <<DEPS; | |
| WARNING: Missing dependencies. Please ensure that the following PTFs are installed: | |
| z/OS V2R2 with all the following PTFs installed: | |
| - UI62788 | |
| - UI46658 | |
| - UI62416 | |
| - UI62415 | |
| z/OS V2R3 with all the following PTFs installed: | |
| - UI61308 | |
| - UI61376 | |
| - UI61747 | |
| - UI61375 | |
| DEPS | |
| $| = 1; | |
| for (my $i=0; $i <= 2; $i++) { | |
| print "."; | |
| sleep 1; | |
| } | |
| $| = 0; | |
| } | |
| (system("mkdir -p $tgtRoot && cp -rmf $ussRoot/* $tgtRoot/") == 0)||die "copy failed"; | |
| } | |
| open (FLIST,"find $tgtRoot -type f 2>/dev/null|")||die "failed to find files under $srcRoot"; | |
| while (<FLIST>) { | |
| my $file=$_; | |
| chomp $file; | |
| if ($file =~ m/\/xmits\/$sqfHLQ.*.XMIT$/) { | |
| push @listOfDatasets,$file; | |
| } else { | |
| push @files,$file; | |
| } | |
| } | |
| close FLIST; | |
| foreach my $ds (@listOfDatasets) { | |
| if (&isUninstall) { | |
| print "<DEB> deleting ".&mapDatasetName($ds)."\n"; | |
| &deleteDS(&mapDatasetName($ds)) || print "<DEB> cannot delete ".&mapDatasetName($ds)." -- has it already been deleted?\n"; | |
| } else { | |
| print "<DEB> unloading $ds into ".&mapDatasetName($ds)."\n"; | |
| &receiveDSfromFile($ds, &mapDatasetName($ds)) || die "<ERR> cannot receive $ds to ". &mapDatasetName($ds); | |
| } | |
| } | |
| sleep 120; | |
| if (&isUninstall) { | |
| opendir my $ussbindir, "$ussRoot/" or die "<ERR> cannot open uss.images dir $ussRoot:$!"; | |
| my @ussbinfiles = grep { /[^\.]/ } readdir ($ussbindir); | |
| die "<ERR> $ussbindir is empty" if (scalar(@ussbinfiles)<1); | |
| my $filesToDelete = join(' ',@ussbinfiles); | |
| closedir $ussbindir; | |
| (system("cd $tgtRoot/ && rm -rf $filesToDelete") == 0)||die "delete failed:$!"; | |
| print "<INFO> uninstallation complete!\n"; | |
| } else { | |
| foreach my $f (@files) { | |
| if (-T $f) { | |
| print "<DEB> processing file $f\n"; | |
| &doReplaceDataset($f) || die "cannot parse $f to replace dataset"; | |
| &doReplaceRoot($f) || die "cannot parse $f to replace HFS root"; | |
| } else { | |
| print "<DEB> skipping non-text file $f\n"; | |
| } | |
| } | |
| &runIVP() || die "fail to verify installation"; | |
| print "<INFO> installation complete!\n"; | |
| } | |
| sub runIVP { | |
| my $temphello="._temp.hello.cpp"; | |
| open (FHELLO,">$temphello")||die "failed to oepn $temphello"; | |
| print FHELLO "#include <iostream>\n"; | |
| print FHELLO "using namespace std;\n"; | |
| print FHELLO "int main () {\n"; | |
| print FHELLO " cout << \"Hello C++ World!\" << endl;\n"; | |
| print FHELLO " return 0;\n"; | |
| print FHELLO "}\n"; | |
| close FHELLO; | |
| my $cmd="$tgtRoot/njsc++ $temphello -o hello -qphaseid && $tgtRoot/run ./hello && rm -f $temphello hello"; | |
| print "<INFO> running : $cmd!\n"; | |
| return(system("$cmd")==0); | |
| } | |
| sub doReplaceDataset { | |
| my ($file) = @_; | |
| my $ofile = "${file}._temp_out"; | |
| open (FIN,"<$file")||die "failed to open $file to read"; | |
| open (FOUT,">$ofile")||die "failed to open ofile to write"; | |
| while (<FIN>) { | |
| my $line=$_; | |
| $line=~s/$rplHLQ/$usrHLQ/ig; | |
| $line=~s/$rplLEHLQ/$leHLQ/ig; | |
| $line=~s/$rplRTEHLQ/$rteHLQ/ig; | |
| print FOUT $line; | |
| } | |
| close FIN; | |
| close FOUT; | |
| (system("mv $ofile $file && chmod 755 $file")==0)||die " failed to rename $ofile to $file"; | |
| return 1; | |
| } | |
| sub doReplaceRoot { | |
| my ($file) = @_; | |
| my $ofile = "${file}._temp_out"; | |
| open (FIN,"<$file")||die "failed to open $file to read"; | |
| open (FOUT,">$ofile")||die "failed to open ofile to write"; | |
| while (<FIN>) { | |
| my $line=$_; | |
| if ($line=~m/$rplRoot/) { | |
| $line=~s/$rplRoot/$tgtRoot/g; | |
| #print "new line >>> $file >>> $line"; | |
| } | |
| print FOUT $line; | |
| } | |
| close FIN; | |
| close FOUT; | |
| (system("mv $ofile $file && chmod 755 $file")==0)||die " failed to rename $ofile to $file"; | |
| return 1; | |
| } | |
| sub mapDatasetName { | |
| my ($dataset) = @_; | |
| if ($dataset =~ m/.*\/$sqfHLQ\.([^\/]*)\.XMIT$/g) { | |
| $dataset = "$usrHLQ.$1"; | |
| } | |
| return $dataset; | |
| } | |
| sub receiveDSfromFile { | |
| my ($file, $dataset) = @_; | |
| my $tempDS = getTempDSName(); | |
| if (! copyFileToSequentialDS($file, $tempDS)) { | |
| warn "An error occurred while copying file $file to dataset $tempDS. -- $!"; | |
| return 0; | |
| } | |
| if (! receiveDSfromDS($tempDS, $dataset)) { | |
| warn "An error occurred while receiving temporary dataset $tempDS to dataset $dataset."; | |
| return 0; | |
| } | |
| if (! deleteDS($tempDS)) { | |
| warn "An error occurred when deleting $tempDS."; | |
| return 0; | |
| } | |
| return 1; | |
| } | |
| sub submit_jcl { | |
| open (FJCL,">.tempjcl")||die "failed to open .tempjcl"; | |
| my (@list) = @_; | |
| foreach my $line ( @list ) { | |
| print FJCL "$line\n"; | |
| } | |
| close FJCL; | |
| my $cmd = "submit .tempjcl"; | |
| return (system ($cmd) == 0); | |
| } | |
| sub receiveDSfromDS { | |
| my ($in_dataset, $target_dataset) = @_; | |
| $in_dataset=uc($in_dataset); | |
| $target_dataset=uc($target_dataset); | |
| my @jcl; | |
| my $hostname=uc(`hostname -s`); | |
| chomp($hostname); | |
| return 0 if (!$in_dataset || !$target_dataset || !$user || !$hostname); | |
| my @receive_jcl = ( | |
| "//$jclJobName JOB ($accinfo),'RECEIVE',MSGLEVEL=(1,1),MSGCLASS=$msgCLS,", | |
| "// CLASS=A,REGION=0M,USER=$user", | |
| "//REC EXEC PGM=IKJEFT01,DYNAMNBR=3000", | |
| "//SYSTSPRT DD SYSOUT=*", | |
| "//SYSPRINT DD SYSOUT=*", | |
| "//SYSTSIN DD DATA,DLM='!!'", | |
| " RECEIVE +", | |
| " INDATASET('$in_dataset')", | |
| " DATASET('$target_dataset')".($jclVol?' +':''), | |
| ($jclVol?$jclVol:()), | |
| ); | |
| push (@receive_jcl, "!!"); | |
| push (@receive_jcl, "//"); | |
| submit_jcl(@receive_jcl); | |
| return 1; | |
| } | |
| sub copyFileToSequentialDS { | |
| my ($file, $dataset) = @_; | |
| return 0 if (!$dataset) && (!$file); | |
| my $num_cyls = getNumCylinders($file); | |
| #The space parameter doesn't seem to work properly and the documentation is incorrect. | |
| #It seems that we always get 1 cylinder for the primary extent, so I have specified the | |
| #required size twice, for primary and secondary allocation units. | |
| my $copy_cmd = "cp -B -P \"recfm=fb, lrecl=80, blksize=3120, space=(cyl,($num_cyls,$num_cyls))\" $file \"//'$dataset'\""; | |
| return (system ($copy_cmd) == 0); | |
| } | |
| sub getNumCylinders { | |
| my ($file) = @_; | |
| return 0 if (!$file); | |
| my $size = -s $file; | |
| #Determine the number of cylinders that we need for the DS (always round up by 1) | |
| my $num_cyls = int($size / $BYTES_PER_CYLINDER) + 1; | |
| } | |
| sub deleteDS { | |
| my ($dataset) = @_; | |
| $dataset=uc($dataset); | |
| my @delete_jcl = ( | |
| "//$jclJobName JOB ($accinfo),", | |
| "// 'DELETE',", | |
| "// MSGLEVEL=(1,1),", | |
| "// MSGCLASS=$msgCLS,", | |
| "// CLASS=A,", | |
| "// USER=$user", | |
| "//DELETE EXEC PGM=IEFBR14", | |
| "//ACLBSR1 DD DISP=(MOD,DELETE,DELETE),", | |
| "// DSN=$dataset,", | |
| "// SPACE=(TRK,(1,1))", | |
| "//", | |
| ); | |
| } | |
| sub getTempDSName { | |
| my $time = time(); | |
| my @random_chars = ('A'..'Z'); | |
| #<LAST 7 DIGITS OF CURRENT TIME IN MS>.T<PID> | |
| $random_string = "T" . substr($time, -7); | |
| $random_string .= "." . $random_chars[int(rand(scalar(@random_chars)))]; | |
| $random_string .= int(rand(scalar(9999999))); | |
| my $tempDS = "$usrHLQ.TMP.$random_string"; | |
| return $tempDS; | |
| } | |
| sub isUninstall { | |
| return ($uninstall?1:0); | |
| } | |
| 1; | |
| =pod | |
| =head1 NAME | |
| B<unpack.pl> - install or uninstall the compiler from downloaded USS pax file | |
| =head1 SYNOPSIS | |
| B<unpack.pl> [B<-uninstall>] [--] [B<arg>]* | |
| =head1 DESCRIPTION | |
| description - this script will create or delete the compiler driver based on: | |
| 1. HFS parts for compiler placed under the uss.images HFS directory | |
| 2. MVS datasets for compiler packaged as sequential datasets placed under uss.images/xmits HFS directory | |
| 3. When no argument is passed to the script, it will install/restore the compiler; when -uninstall is passed to the script, it will uninstall the compiler. | |
| 4. The compiler will be installed/restored under the directory where this script is run, while the MVS portion of the compiler will be installed/restored under the user's High Level Qualifier where the script is run. Optionally, the MVS dataset High Level Qualifier can be overwritten by the environment variable COMPILER_INSTALL_HLQ if it is set. | |
| =head1 OPTIONS | |
| B<-uninstall> | |
| =over 3 | |
| specifies whether the operation is an uninstallation, by default the script does the installation. | |
| =back | |
| =head1 EXAMPLES | |
| example - | |
| =over 3 | |
| To install the compiler under the current directory, run: | |
| C<./unpack.pl> | |
| =back | |
| =head1 COPYRIGHT | |
| Copyright 2017 IBM Corporation | |
| =cut |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment