#************************************************************************* # # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # Copyright 2008 by Sun Microsystems, Inc. # # OpenOffice.org - a multi-platform office productivity suite # # $RCSfile: epmfile.pm,v $ # # $Revision: 1.85.28.3 $ # # This file is part of OpenOffice.org. # # OpenOffice.org is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License version 3 # only, as published by the Free Software Foundation. # # OpenOffice.org is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License version 3 for more details # (a copy is included in the LICENSE file that accompanied this code). # # You should have received a copy of the GNU Lesser General Public License # version 3 along with OpenOffice.org. If not, see # # for a copy of the LGPLv3 License. # #************************************************************************* package installer::epmfile; use Cwd; use installer::converter; use installer::existence; use installer::exiter; use installer::files; use installer::globals; use installer::logger; use installer::packagelist; use installer::pathanalyzer; use installer::remover; use installer::scriptitems; use installer::systemactions; use installer::worker; use POSIX; ############################################################################ # The header file contains the strings for the epm header in all languages ############################################################################ sub get_string_from_headerfile { my ($searchstring, $language, $fileref) = @_; my $returnstring = ""; my $onestring = ""; my $englishstring = ""; my $foundblock = 0; my $foundstring = 0; my $foundenglishstring = 0; my $englishidentifier = "01"; $searchstring = "[" . $searchstring . "]"; for ( my $i = 0; $i <= $#{$fileref}; $i++ ) { my $line = ${$fileref}[$i]; if ( $line =~ /^\s*\Q$searchstring\E\s*$/ ) { $foundblock = 1; my $counter = $i + 1; $line = ${$fileref}[$counter]; # Beginning of the next block oder Dateiende while ((!($line =~ /^\s*\[\s*\w+\s*\]\s*$/ )) && ( $counter <= $#{$fileref} )) { if ( $line =~ /^\s*\Q$language\E\s+\=\s*\"(.*)\"\s*$/ ) { $onestring = $1; $foundstring = 1; last; } if ( $line =~ /^\s*\Q$englishidentifier\E\s+\=\s*\"(.*)\"\s*$/ ) { $englishstring = $1; $foundenglishstring = 1; } $counter++; $line = ${$fileref}[$counter]; } } } if ( $foundstring ) { $returnstring = $onestring; } else { if ( $foundenglishstring ) { $returnstring = $englishstring; } else { installer::exiter::exit_program("ERROR: No string found for $searchstring in epm header file (-h)", "get_string_from_headerfile"); } } return \$returnstring; } ########################################################## # Filling the epm file with directories, files and links ########################################################## sub put_directories_into_epmfile { my ($directoriesarrayref, $epmfileref, $allvariables, $packagerootpath) = @_; my $group = "bin"; if ( $installer::globals::islinuxbuild ) { $group = "root"; } for ( my $i = 0; $i <= $#{$directoriesarrayref}; $i++ ) { my $onedir = ${$directoriesarrayref}[$i]; my $dir = ""; if ( $onedir->{'Dir'} ) { $dir = $onedir->{'Dir'}; } # if (!($dir =~ /\bPREDEFINED_/ )) if ((!($dir =~ /\bPREDEFINED_/ )) || ( $dir =~ /\bPREDEFINED_PROGDIR\b/ )) { my $hostname = $onedir->{'HostName'}; # not including simple directory "/opt" # if (( $allvariables->{'SETSTATICPATH'} ) && ( $hostname eq $packagerootpath )) { next; } my $line = "d 755 root $group $hostname -\n"; push(@{$epmfileref}, $line) } } } sub put_files_into_epmfile { my ($filesinproductarrayref, $epmfileref) = @_; for ( my $i = 0; $i <= $#{$filesinproductarrayref}; $i++ ) { my $onefile = ${$filesinproductarrayref}[$i]; my $unixrights = $onefile->{'UnixRights'}; my $destination = $onefile->{'destination'}; my $sourcepath = $onefile->{'sourcepath'}; my $filetype = "f"; my $styles = ""; if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; } if ( $styles =~ /\bCONFIGFILE\b/ ) { $filetype = "c"; } my $group = "bin"; if ( $installer::globals::islinuxbuild ) { $group = "root"; } if (( $installer::globals::issolarisbuild ) && ( $onefile->{'SolarisGroup'} )) { $group = $onefile->{'SolarisGroup'}; } my $line = "$filetype $unixrights root $group $destination $sourcepath\n"; push(@{$epmfileref}, $line); } } sub put_links_into_epmfile { my ($linksinproductarrayref, $epmfileref) = @_; my $group = "bin"; if ( $installer::globals::islinuxbuild ) { $group = "root"; } for ( my $i = 0; $i <= $#{$linksinproductarrayref}; $i++ ) { my $onelink = ${$linksinproductarrayref}[$i]; my $destination = $onelink->{'destination'}; my $destinationfile = $onelink->{'destinationfile'}; my $line = "l 000 root $group $destination $destinationfile\n"; push(@{$epmfileref}, $line) } } sub put_unixlinks_into_epmfile { my ($unixlinksinproductarrayref, $epmfileref) = @_; my $group = "bin"; if ( $installer::globals::islinuxbuild ) { $group = "root"; } for ( my $i = 0; $i <= $#{$unixlinksinproductarrayref}; $i++ ) { my $onelink = ${$unixlinksinproductarrayref}[$i]; my $destination = $onelink->{'destination'}; my $target = $onelink->{'Target'}; my $line = "l 000 root $group $destination $target\n"; push(@{$epmfileref}, $line) } } ############################################### # Creating epm header file ############################################### sub create_epm_header { my ($variableshashref, $filesinproduct, $languagesref, $onepackage) = @_; my @epmheader = (); my ($licensefilename, $readmefilename); my $foundlicensefile = 0; my $foundreadmefile = 0; my $line = ""; my $infoline = ""; # %product OpenOffice.org Software # %version 2.0 # %description A really great software # %copyright 1999-2003 by OOo # %vendor OpenOffice.org # %license /test/replace/01/LICENSE01 # %readme /test/replace/01/README01 # %requires foo # %provides bar # The first language in the languages array determines the language of license and readme file my $searchlanguage = ${$languagesref}[0]; # using the description for the %product line in the epm list file my $productnamestring = $onepackage->{'description'}; installer::packagelist::resolve_packagevariables(\$productnamestring, $variableshashref, 0); if ( $variableshashref->{'PRODUCTEXTENSION'} ) { $productnamestring = $productnamestring . " " . $variableshashref->{'PRODUCTEXTENSION'}; } $line = "%product" . " " . $productnamestring . "\n"; push(@epmheader, $line); # Determining the release version # This release version has to be listed in the line %version : %version versionnumber releasenumber # if ( $variableshashref->{'PACKAGEVERSION'} ) { $installer::globals::packageversion = $variableshashref->{'PACKAGEVERSION'}; } if ( ! $onepackage->{'packageversion'} ) { installer::exiter::exit_program("ERROR: No packageversion defined for package: $onepackage->{'module'}!", "create_epm_header"); } $installer::globals::packageversion = $onepackage->{'packageversion'}; installer::packagelist::resolve_packagevariables(\$installer::globals::packageversion, $variableshashref, 0); if ( $variableshashref->{'PACKAGEREVISION'} ) { $installer::globals::packagerevision = $variableshashref->{'PACKAGEREVISION'}; } $line = "%version" . " " . $installer::globals::packageversion . "\n"; push(@epmheader, $line); $line = "%release" . " " . $installer::globals::packagerevision . "\n"; if ( $installer::globals::islinuxrpmbuild ) { $line = "%release" . " " . $installer::globals::buildid . "\n"; } push(@epmheader, $line); # Description, Copyright and Vendor are multilingual and are defined in # the string file for the header file ($headerfileref) my $descriptionstring = $onepackage->{'description'}; installer::packagelist::resolve_packagevariables(\$descriptionstring, $variableshashref, 0); $line = "%description" . " " . $descriptionstring . "\n"; push(@epmheader, $line); my $copyrightstring = $onepackage->{'copyright'}; installer::packagelist::resolve_packagevariables(\$copyrightstring, $variableshashref, 0); $line = "%copyright" . " " . $copyrightstring . "\n"; push(@epmheader, $line); my $vendorstring = $onepackage->{'vendor'}; installer::packagelist::resolve_packagevariables(\$vendorstring, $variableshashref, 0); $line = "%vendor" . " " . $vendorstring . "\n"; push(@epmheader, $line); # License and Readme file can be included automatically from the file list if ( $installer::globals::iswindowsbuild ) { $licensefilename = "license.txt"; $readmefilename = "readme.txt"; } else { $licensefilename = "LICENSE"; $readmefilename = "README"; } if (( $installer::globals::languagepack ) # in language packs the files LICENSE and README are removed, because they are not language specific || ( $variableshashref->{'NO_README_IN_ROOTDIR'} )) { if ( $installer::globals::iswindowsbuild ) { $licensefilename = "license_$searchlanguage.txt"; $readmefilename = "readme_$searchlanguage.txt"; } else { $licensefilename = "LICENSE_$searchlanguage"; $readmefilename = "README_$searchlanguage"; } } my $license_in_package_defined = 0; if ( $installer::globals::issolarisbuild ) { if ( $onepackage->{'solariscopyright'} ) { $licensefilename = $onepackage->{'solariscopyright'}; $license_in_package_defined = 1; } } # searching for and readme file for ( my $i = 0; $i <= $#{$filesinproduct}; $i++ ) { my $onefile = ${$filesinproduct}[$i]; my $filename = $onefile->{'Name'}; if ( $filename eq $readmefilename ) { $foundreadmefile = 1; $line = "%readme" . " " . $onefile->{'sourcepath'} . "\n"; push(@epmheader, $line); last; } } # searching for and license file if ( $license_in_package_defined ) { my $fileref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$licensefilename, "" , 0); if ( $$fileref eq "" ) { installer::exiter::exit_program("ERROR: Could not find license file $licensefilename!", "create_epm_header"); } $infoline = "Using license file: \"$$fileref\"!\n"; push(@installer::globals::logfileinfo, $infoline); $foundlicensefile = 1; $line = "%license" . " " . $$fileref . "\n"; push(@epmheader, $line); } else { for ( my $i = 0; $i <= $#{$filesinproduct}; $i++ ) { my $onefile = ${$filesinproduct}[$i]; my $filename = $onefile->{'Name'}; if ( $filename eq $licensefilename ) { $foundlicensefile = 1; $line = "%license" . " " . $onefile->{'sourcepath'} . "\n"; push(@epmheader, $line); last; } } } if (!($foundlicensefile)) { installer::exiter::exit_program("ERROR: Could not find license file $licensefilename", "create_epm_header"); } if (!($foundreadmefile)) { installer::exiter::exit_program("ERROR: Could not find readme file $readmefilename", "create_epm_header"); } # including %replaces my $replaces = ""; if (( $installer::globals::issolarispkgbuild ) && ( ! $installer::globals::patch )) { $replaces = "solarisreplaces"; # the name in the packagelist } elsif (( $installer::globals::islinuxbuild ) && ( ! $installer::globals::patch )) { $replaces = "linuxreplaces"; # the name in the packagelist } if (( $replaces ) && ( ! $installer::globals::patch )) { if ( $onepackage->{$replaces} ) { my $replacesstring = $onepackage->{$replaces}; my $allreplaces = installer::converter::convert_stringlist_into_array(\$replacesstring, ","); for ( my $i = 0; $i <= $#{$allreplaces}; $i++ ) { my $onereplaces = ${$allreplaces}[$i]; $onereplaces =~ s/\s*$//; installer::packagelist::resolve_packagevariables(\$onereplaces, $variableshashref, 1); if ( $installer::globals::linuxlinkrpmprocess ) { $onereplaces = $onereplaces . "u"; } $line = "%replaces" . " " . $onereplaces . "\n"; push(@epmheader, $line); # Force the openofficeorg packages to get removed, # see http://www.debian.org/doc/debian-policy/ch-relationships.html # 7.5.2 Replacing whole packages, forcing their removal if ( $installer::globals::debian ) { $line = "%incompat" . " " . $onereplaces . "\n"; push(@epmheader, $line); } } if ( $installer::globals::debian && $variableshashref->{'UNIXPRODUCTNAME'} eq 'openoffice.org' ) { $line = "%provides" . " openoffice.org-unbundled\n"; push(@epmheader, $line); $line = "%incompat" . " openoffice.org-bundled\n"; push(@epmheader, $line); } } } # including the directives for %requires and %provides my $provides = ""; my $requires = ""; if ( $installer::globals::issolarispkgbuild ) { $provides = "solarisprovides"; # the name in the packagelist $requires = "solarisrequires"; # the name in the packagelist } elsif ( $installer::globals::isfreebsdpkgbuild ) { $provides = "freebsdprovides"; # the name in the packagelist $requires = "freebsdrequires"; # the name in the packagelist } elsif (( $installer::globals::islinuxrpmbuild ) && ( $installer::globals::patch ) && ( exists($onepackage->{'linuxpatchrequires'}) )) { $provides = "provides"; # the name in the packagelist $requires = "linuxpatchrequires"; # the name in the packagelist } else { $provides = "provides"; # the name in the packagelist $requires = "requires"; # the name in the packagelist } # if ( $installer::globals::patch ) # { # $onepackage->{$provides} = ""; # $onepackage->{$requires} = ""; # } if ( $onepackage->{$provides} ) { my $providesstring = $onepackage->{$provides}; my $allprovides = installer::converter::convert_stringlist_into_array(\$providesstring, ","); for ( my $i = 0; $i <= $#{$allprovides}; $i++ ) { my $oneprovides = ${$allprovides}[$i]; $oneprovides =~ s/\s*$//; installer::packagelist::resolve_packagevariables(\$oneprovides, $variableshashref, 1); if ( $installer::globals::linuxlinkrpmprocess ) { $oneprovides = $oneprovides . "u"; } $line = "%provides" . " " . $oneprovides . "\n"; push(@epmheader, $line); } } if ( $onepackage->{$requires} ) { my $requiresstring = $onepackage->{$requires}; if ( $installer::globals::add_required_package ) { $requiresstring = $requiresstring . "," . $installer::globals::add_required_package; } # The requires string can contain the separator "," in the names (descriptions) of the packages # (that are required for Solaris depend files). Therefore "," inside such a description has to # masked with a backslash. # This masked separator need to be found and replaced, before the stringlist is converted into an array. # This replacement has to be turned back after the array is created. my $replacementstring = "COMMAREPLACEMENT"; $requiresstring = installer::converter::replace_masked_separator($requiresstring, ",", "$replacementstring"); my $allrequires = installer::converter::convert_stringlist_into_array(\$requiresstring, ","); installer::converter::resolve_masked_separator($allrequires, ",", $replacementstring); for ( my $i = 0; $i <= $#{$allrequires}; $i++ ) { my $onerequires = ${$allrequires}[$i]; $onerequires =~ s/\s*$//; installer::packagelist::resolve_packagevariables(\$onerequires, $variableshashref, 0); # Special handling for Solaris. In depend files, the names of the packages are required, not # only the abbreviation. Therefore there is a special syntax for names in packagelist: # solarisrequires = "SUNWcar (Name="Package name of SUNWcar"),SUNWkvm (Name="Package name of SUNWcar"), ... if ( $installer::globals::issolarispkgbuild ) { if ( $onerequires =~ /^\s*(.*?)\s+\(\s*Name\s*=\s*\"(.*?)\"\s*\)\s*$/ ) { $onerequires = $1; $packagename = $2; $installer::globals::dependfilenames{$onerequires} = $packagename; } } $line = "%requires" . " " . $onerequires . "\n"; push(@epmheader, $line); } } else { if ( $installer::globals::add_required_package ) { my $requiresstring = $installer::globals::add_required_package; my $replacementstring = "COMMAREPLACEMENT"; $requiresstring = installer::converter::replace_masked_separator($requiresstring, ",", "$replacementstring"); my $allrequires = installer::converter::convert_stringlist_into_array(\$requiresstring, ","); installer::converter::resolve_masked_separator($allrequires, ",", $replacementstring); for ( my $i = 0; $i <= $#{$allrequires}; $i++ ) { my $onerequires = ${$allrequires}[$i]; $onerequires =~ s/\s*$//; installer::packagelist::resolve_packagevariables(\$onerequires, $variableshashref, 0); # Special handling for Solaris. In depend files, the names of the packages are required, not # only the abbreviation. Therefore there is a special syntax for names in packagelist: # solarisrequires = "SUNWcar (Name="Package name of SUNWcar"),SUNWkvm (Name="Package name of SUNWcar"), ... if ( $installer::globals::issolarispkgbuild ) { if ( $onerequires =~ /^\s*(.*?)\s+\(\s*Name\s*=\s*\"(.*?)\"\s*\)\s*$/ ) { $onerequires = $1; $packagename = $2; $installer::globals::dependfilenames{$onerequires} = $packagename; } } $line = "%requires" . " " . $onerequires . "\n"; push(@epmheader, $line); } } } return \@epmheader; } ####################################### # Adding header to epm file ####################################### sub adding_header_to_epm_file { my ($epmfileref, $epmheaderref) = @_; for ( my $i = 0; $i <= $#{$epmheaderref}; $i++ ) { push( @{$epmfileref}, ${$epmheaderref}[$i] ); } push( @{$epmfileref}, "\n\n" ); } ##################################################### # Replace one in shell scripts ( ${VARIABLENAME} ) ##################################################### sub replace_variable_in_shellscripts { my ($scriptref, $variable, $searchstring) = @_; for ( my $i = 0; $i <= $#{$scriptref}; $i++ ) { ${$scriptref}[$i] =~ s/\$\{$searchstring\}/$variable/g; } } ################################################### # Replace one in shell scripts ( %VARIABLENAME ) ################################################### sub replace_percent_variable_in_shellscripts { my ($scriptref, $variable, $searchstring) = @_; for ( my $i = 0; $i <= $#{$scriptref}; $i++ ) { ${$scriptref}[$i] =~ s/\%$searchstring/$variable/g; } } ################################################ # Replacing many variables in shell scripts ################################################ sub replace_many_variables_in_shellscripts { my ($scriptref, $variableshashref) = @_; my $key; foreach $key (keys %{$variableshashref}) { my $value = $variableshashref->{$key}; if ( ! $value =~ /.oxt/ ) { $value = lc($value); } # lowercase ! if ( $installer::globals::issolarisbuild) { $value =~ s/\.org/org/g; } # openofficeorg instead of openoffice.org replace_variable_in_shellscripts($scriptref, $value, $key); } } ####################################### # Setting oxt file name variable ####################################### sub set_oxt_filename { my ($filesinpackage, $allvariables) = @_; for ( my $i = 0; $i <= $#{$filesinpackage}; $i++ ) { my $onefile = ${$filesinpackage}[$i]; if ( $onefile->{'Name'} =~ /.oxt\s*$/ ) { $allvariables->{'OXTFILENAME'} = $onefile->{'Name'}; # $allvariables->{'FULLOXTFILENAME'} = $onefile->{'destination'}; last; # only one oxt file for each rpm! } } } ####################################### # Adding shell scripts to epm file ####################################### sub adding_shellscripts_to_epm_file { my ($epmfileref, $shellscriptsfilename, $localrootpath, $allvariableshashref, $filesinpackage) = @_; # Setting variable for ${OXTFILENAME} into $allvariableshashref, if this is a RPM with an extension set_oxt_filename($filesinpackage, $allvariableshashref); # $installer::globals::shellscriptsfilename push( @{$epmfileref}, "\n\n" ); my $shellscriptsfileref = installer::files::read_file($shellscriptsfilename); replace_variable_in_shellscripts($shellscriptsfileref, $localrootpath, "rootpath"); replace_many_variables_in_shellscripts($shellscriptsfileref, $allvariableshashref); for ( my $i = 0; $i <= $#{$shellscriptsfileref}; $i++ ) { push( @{$epmfileref}, ${$shellscriptsfileref}[$i] ); } push( @{$epmfileref}, "\n" ); } ################################################# # Determining the epm on the system ################################################# sub find_epm_on_system { my ($includepatharrayref) = @_; installer::logger::include_header_into_logfile("Check epm on system"); my $epmname = "epm"; # epm should be defined through the configure script but we need to # check for it to be defined because of the Sun environment. # Check the environment variable first and if it is not defined, # or if it is but the location is not executable, search further. # It has to be found in the solver or it has to be in the path # (saved in $installer::globals::epm_in_path) or we get the specified # one through the environment (i.e. when --with-epm=... is specified) if ($ENV{'EPM'}) { if (($ENV{'EPM'} ne "") && (-x "$ENV{'EPM'}")) { $epmname = $ENV{'EPM'}; } elsif ( ($ENV{'EPM'} eq "no") || ($ENV{'EPM'} eq "internal") ) { $epmname = "epm"; } else { installer::exiter::exit_program("Environment variable EPM set (\"$ENV{'EPM'}\"), but file does not exist or is not executable!", "find_epm_on_system"); } } else { my $epmfileref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$epmname, $includepatharrayref, 0); if (($$epmfileref eq "") && (!($installer::globals::epm_in_path))) { installer::exiter::exit_program("ERROR: Could not find program $epmname!", "find_epm_on_system"); } if (($$epmfileref eq "") && ($installer::globals::epm_in_path)) { $epmname = $installer::globals::epm_path; } if (!($$epmfileref eq "")) { $epmname = $$epmfileref; } } my $infoline = "Using epmfile: $epmname\n"; push( @installer::globals::logfileinfo, $infoline); return $epmname; } ################################################# # Determining the epm patch state # saved in $installer::globals::is_special_epm ################################################# sub set_patch_state { my ($epmexecutable) = @_; my $infoline = ""; my $systemcall = "$epmexecutable |"; open (EPMPATCH, "$systemcall"); while () { chop; if ( $_ =~ /Patched for OpenOffice.org/ ) { $installer::globals::is_special_epm = 1; } } close (EPMPATCH); if ( $installer::globals::is_special_epm ) { $infoline = "\nPatch state: This is a patched version of epm!\n\n"; push( @installer::globals::logfileinfo, $infoline); } else { $infoline = "\nPatch state: This is an unpatched version of epm!\n\n"; push( @installer::globals::logfileinfo, $infoline); } } ################################################# # LD_PRELOAD string for Debian packages ################################################# sub get_ld_preload_string { my ($includepatharrayref) = @_; my $getuidlibraryname = "getuid.so"; my $getuidlibraryref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$getuidlibraryname, $includepatharrayref, 0); if ($$getuidlibraryref eq "") { installer::exiter::exit_program("ERROR: Could not find $getuidlibraryname!", "get_ld_preload_string"); } my $ldpreloadstring = "LD_PRELOAD=" . $$getuidlibraryref; return $ldpreloadstring; } ################################################# # Calling epm to create the installation sets ################################################# sub call_epm { my ($epmname, $epmlistfilename, $packagename, $includepatharrayref) = @_; installer::logger::include_header_into_logfile("epm call for $packagename"); my $packageformat = $installer::globals::packageformat; my $localpackagename = $packagename; # Debian allows only lowercase letters in package name if ( $installer::globals::debian ) { $localpackagename = lc($localpackagename); } #if ( $installer::globals::debian ) { $localpackagename =~ s/_/-/g; } $localpackagename =~ s/_//g; $localpackagename =~ s/-//g; $localpackagename =~ s/.//g; my $outdirstring = ""; if ( $installer::globals::epmoutpath ne "" ) { $outdirstring = " --output-dir $installer::globals::epmoutpath"; } # Debian package build needs a LD_PRELOAD for correct rights my $ldpreloadstring = ""; if ( $installer::globals::debian ) { $ldpreloadstring = get_ld_preload_string($includepatharrayref) . " "; } my $extraflags = ""; if ($ENV{'EPM_FLAGS'}) { $extraflags = $ENV{'EPM_FLAGS'}; } my $systemcall = $ldpreloadstring . $epmname . " -f " . $packageformat . " " . $extraflags . " " . $localpackagename . " " . $epmlistfilename . $outdirstring . " -v " . " 2\>\&1 |"; installer::logger::print_message( "... $systemcall ...\n" ); my $maxepmcalls = 3; for ( my $i = 1; $i <= $maxepmcalls; $i++ ) { my @epmoutput = (); open (EPM, "$systemcall"); while () {push(@epmoutput, $_); } close (EPM); my $returnvalue = $?; # $? contains the return value of the systemcall my $infoline = "Systemcall (Try $i): $systemcall\n"; push( @installer::globals::logfileinfo, $infoline); for ( my $j = 0; $j <= $#epmoutput; $j++ ) { if ( $i < $maxepmcalls ) { $epmoutput[$j] =~ s/\bERROR\b/PROBLEM/ig; } push( @installer::globals::logfileinfo, "$epmoutput[$j]"); } if ($returnvalue) { $infoline = "Try $i : Could not execute \"$systemcall\"!\n"; push( @installer::globals::logfileinfo, $infoline); if ( $i == $maxepmcalls ) { installer::exiter::exit_program("ERROR: \"$systemcall\"!", "call_epm"); } } else { installer::logger::print_message( "Success (Try $i): \"$systemcall\"\n" ); $infoline = "Success: Executed \"$systemcall\" successfully!\n"; push( @installer::globals::logfileinfo, $infoline); last; } } } ##################################################################### # Adding the new line for relocatables into pkginfo file (Solaris) # or spec file (Linux) created by epm ##################################################################### sub add_one_line_into_file { my ($file, $insertline, $filename) = @_; if ( $installer::globals::issolarispkgbuild ) { push(@{$file}, $insertline); # simply adding at the end of pkginfo file } if ( $installer::globals::islinuxrpmbuild ) { # Adding behind the line beginning with: Group: my $inserted_line = 0; for ( my $i = 0; $i <= $#{$file}; $i++ ) { if ( ${$file}[$i] =~ /^\s*Group\:\s*/ ) { splice(@{$file},$i+1,0,$insertline); $inserted_line = 1; last; } } if (! $inserted_line) { installer::exiter::exit_program("ERROR: Did not find string \"Group:\" in file: $filename", "add_one_line_into_file"); } } $insertline =~ s/\s*$//; # removing line end for correct logging my $infoline = "Success: Added line $insertline into file $filename!\n"; push( @installer::globals::logfileinfo, $infoline); } ##################################################################### # Setting the revision VERSION=1.9,REV=66 . # Also adding the new line: "AutoReqProv: no" ##################################################################### sub set_revision_in_pkginfo { my ($file, $filename, $variables) = @_; my $revisionstring = "\,REV\=" . $installer::globals::packagerevision; # Adding also a time string to the revision. Syntax: VERSION=8.0.0,REV=66.2005.01.24 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); $mday = $mday; $mon = $mon + 1; $year = $year + 1900; if ( $mday < 10 ) { $mday = "0" . $mday; } if ( $mon < 10 ) { $mon = "0" . $mon; } $datestring = $year . "." . $mon . "." . $mday; $revisionstring = $revisionstring . "." . $datestring; for ( my $i = 0; $i <= $#{$file}; $i++ ) { if ( ${$file}[$i] =~ /^\s*(VERSION\=.*?)\s*$/ ) { my $oldstring = $1; my $newstring = $oldstring . $revisionstring; # also adding the date string ${$file}[$i] =~ s/$oldstring/$newstring/; my $infoline = "Info: Changed in $filename file: \"$oldstring\" to \"$newstring\"!\n"; push( @installer::globals::logfileinfo, $infoline); last; } } # For Update and Patch reasons, this string can also be kept constant my $pkgversion = "SOLSPARCPKGVERSION"; if ( $installer::globals::issolarisx86build ) { $pkgversion = "SOLIAPKGVERSION"; } if ( $variables->{$pkgversion} ) { if ( $variables->{$pkgversion} ne "FINALVERSION" ) { my $versionstring = $variables->{$pkgversion}; for ( my $i = 0; $i <= $#{$file}; $i++ ) { if ( ${$file}[$i] =~ /^\s*(VERSION\=).*?\s*$/ ) { my $start = $1; my $newstring = $start . $versionstring . "\n"; # setting the complete new string my $oldstring = ${$file}[$i]; ${$file}[$i] = $newstring; $oldstring =~ s/\s*$//; $newstring =~ s/\s*$//; my $infoline = "Info: Changed in $filename file: \"$oldstring\" to \"$newstring\"!\n"; push( @installer::globals::logfileinfo, $infoline); last; } } } } } ######################################################## # Setting Patch information for Respin versions # into pkginfo file. This prevents Respin versions # from patching. ######################################################## sub set_patchlist_in_pkginfo_for_respin { my ($changefile, $filename, $allvariables, $packagename) = @_; my $patchlistname = "SOLSPARCPATCHLISTFORRESPIN"; if ( $installer::globals::issolarisx86build ) { $patchlistname = "SOLIAPATCHLISTFORRESPIN"; } if ( $allvariables->{$patchlistname} ) { # patchlist separator is a blank my $allpatchesstring = $allvariables->{$patchlistname}; my @usedpatches = (); # Analyzing the patchlist # Syntax: 120186-10 126411-01(+core-01) -> use 126411-01 only for core-01 # Syntax: 120186-10 126411-01(-core-01) -> use 126411-01 for all packages except for core-01 my $allpatches = installer::converter::convert_whitespace_stringlist_into_array(\$allpatchesstring); for ( my $i = 0; $i <= $#{$allpatches}; $i++ ) { my $patchdefinition = ${$allpatches}[$i]; my $patchid = ""; my $symbol = ""; my $constraint = ""; my $isusedpatch = 0; if ( $patchdefinition =~ /^\s*(.+)\(([+-])(.+)\)\s*$/ ) { $patchid = $1; $symbol = $2; $constraint = $3; } elsif (( $patchdefinition =~ /\(/ ) || ( $patchdefinition =~ /\)/ )) # small syntax check { # if there is a bracket in the $patchdefinition, but it does not # match the if-condition, this is an erroneous definition. installer::exiter::exit_program("ERROR: Unknown patch string: $patchdefinition", "set_patchlist_in_pkginfo_for_respin"); } else { $patchid = $patchdefinition; $isusedpatch = 1; # patches without constraint are always included } if ( $symbol ne "" ) { if ( $symbol eq "+" ) { if ( $packagename =~ /^.*\Q$constraint\E\s*$/ ) { $isusedpatch = 1; } } if ( $symbol eq "-" ) { if ( ! ( $packagename =~ /^.*\Q$constraint\E\s*$/ )) { $isusedpatch = 1; } } } if ( $isusedpatch ) { push(@usedpatches, $patchid); } } if ( $#usedpatches > -1 ) { my $patchstring = installer::converter::convert_array_to_space_separated_string(\@usedpatches); my $newline = "PATCHLIST=" . $patchstring . "\n"; add_one_line_into_file($changefile, $newline, $filename); # Adding patch info for each used patch in the patchlist for ( my $i = 0; $i <= $#usedpatches; $i++ ) { my $patchid = $usedpatches[$i]; my $key = "PATCH_INFO_" . $patchid; $key =~ s/\s*$//; if ( ! $allvariables->{$key} ) { installer::exiter::exit_program("ERROR: No Patch info available in zip list file for $key", "set_patchlist_in_pkginfo"); } $newline = $key . "=" . $allvariables->{$key} . "\n"; add_one_line_into_file($changefile, $newline, $filename); } } } } ######################################################## # Setting MAXINST=1000 into the pkginfo file. ######################################################## sub set_maxinst_in_pkginfo { my ($changefile, $filename) = @_; my $newline = "MAXINST\=1000\n"; add_one_line_into_file($changefile, $newline, $filename); } ############################################################# # Setting several Solaris variables into the pkginfo file. ############################################################# sub set_solaris_parameter_in_pkginfo { my ($changefile, $filename, $allvariables) = @_; my $newline = ""; # SUNW_PRODNAME # SUNW_PRODVERS # SUNW_PKGVERS # Not: SUNW_PKGTYPE # HOTLINE # EMAIL my $productname = $allvariables->{'PRODUCTNAME'}; $newline = "SUNW_PRODNAME=$productname\n"; add_one_line_into_file($changefile, $newline, $filename); my $productversion = ""; if ( $allvariables->{'PRODUCTVERSION'} ) { $productversion = $allvariables->{'PRODUCTVERSION'}; if ( $allvariables->{'PRODUCTEXTENSION'} ) { $productversion = $productversion . "/" . $allvariables->{'PRODUCTEXTENSION'}; } } $newline = "SUNW_PRODVERS=$productversion\n"; add_one_line_into_file($changefile, $newline, $filename); $newline = "SUNW_PKGVERS=1\.0\n"; add_one_line_into_file($changefile, $newline, $filename); if ( $allvariables->{'SUNW_PKGTYPE'} ) { $newline = "SUNW_PKGTYPE=$allvariables->{'SUNW_PKGTYPE'}\n"; add_one_line_into_file($changefile, $newline, $filename); } $newline = "HOTLINE=Please contact your local service provider\n"; add_one_line_into_file($changefile, $newline, $filename); $newline = "EMAIL=\n"; add_one_line_into_file($changefile, $newline, $filename); } ##################################################################### # epm uses as archtecture for Solaris x86 "i86pc". This has to be # changed to "i386". ##################################################################### sub fix_architecture_setting { my ($changefile) = @_; for ( my $i = 0; $i <= $#{$changefile}; $i++ ) { if ( ${$changefile}[$i] =~ /^\s*ARCH=i86pc\s*$/ ) { ${$changefile}[$i] =~ s/i86pc/i386/; last; } } } ##################################################################### # Adding a new line for topdir into specfile, removing old # topdir if set. ##################################################################### sub set_topdir_in_specfile { my ($changefile, $filename, $newepmdir) = @_; # $newepmdir =~ s/^\s*\.//; # removing leading "." $newepmdir = cwd() . $installer::globals::separator . $newepmdir; # only absolute path allowed # removing "%define _topdir", if existing for ( my $i = 0; $i <= $#{$changefile}; $i++ ) { if ( ${$changefile}[$i] =~ /^\s*\%define _topdir\s+/ ) { my $removeline = ${$changefile}[$i]; $removeline =~ s/\s*$//; splice(@{$changefile},$i,1); my $infoline = "Info: Removed line \"$removeline\" from file $filename!\n"; push( @installer::globals::logfileinfo, $infoline); last; } } # Adding "topdir" behind the line beginning with: Group: my $inserted_line = 0; my $topdirline = "\%define _topdir $newepmdir\n"; for ( my $i = 0; $i <= $#{$changefile}; $i++ ) { if ( ${$changefile}[$i] =~ /^\s*Group\:\s*/ ) { splice(@{$changefile},$i+1,0,$topdirline); $inserted_line = 1; $topdirline =~ s/\s*$//; my $infoline = "Success: Added line $topdirline into file $filename!\n"; push( @installer::globals::logfileinfo, $infoline); } } if (! $inserted_line) { installer::exiter::exit_program("ERROR: Did not find string \"Group:\" in file: $filename", "set_topdir_in_specfile"); } } ##################################################################### # Setting the packager in the spec file # Syntax: Packager: abc@def ##################################################################### sub set_packager_in_specfile { my ($changefile) = @_; my $packager = $installer::globals::longmanufacturer; for ( my $i = 0; $i <= $#{$changefile}; $i++ ) { if ( ${$changefile}[$i] =~ /^\s*Packager\s*:\s*(.+?)\s*$/ ) { my $oldstring = $1; ${$changefile}[$i] =~ s/\Q$oldstring\E/$packager/; my $infoline = "Info: Changed Packager in spec file from $oldstring to $packager!\n"; push( @installer::globals::logfileinfo, $infoline); last; } } } ##################################################################### # Setting the requirements in the spec file (i81494) # Syntax: PreReq: "requirements" (only for shared extensions) ##################################################################### sub set_prereq_in_specfile { my ($changefile) = @_; my $prereq = "PreReq:"; for ( my $i = 0; $i <= $#{$changefile}; $i++ ) { if ( ${$changefile}[$i] =~ /^\s*Requires:\s*(.+?)\s*$/ ) { my $oldstring = ${$changefile}[$i]; ${$changefile}[$i] =~ s/Requires:/$prereq/; my $infoline = "Info: Changed requirements in spec file from $oldstring to ${$changefile}[$i]!\n"; push( @installer::globals::logfileinfo, $infoline); } } } ##################################################################### # Setting the Auto[Req]Prov line and __find_requires ##################################################################### sub set_autoprovreq_in_specfile { my ($changefile, $findrequires, $bindir) = @_; my $autoreqprovline; if ( $findrequires ) { $autoreqprovline = "AutoProv\: no\n%define __find_requires $bindir/$findrequires\n"; } else { $autoreqprovline = "AutoReqProv\: no\n"; } for ( my $i = 0; $i <= $#{$changefile}; $i++ ) { # Adding "autoreqprov" behind the line beginning with: Group: if ( ${$changefile}[$i] =~ /^\s*Group\:\s*/ ) { splice(@{$changefile},$i+1,0,$autoreqprovline); $autoreqprovline =~ s/\s*$//; $infoline = "Success: Added line $autoreqprovline into spec file!\n"; push( @installer::globals::logfileinfo, $infoline); last; } } } ##################################################################### # Replacing Copyright with License in the spec file # Syntax: License: LGPL, SISSL ##################################################################### sub set_license_in_specfile { my ($changefile, $variableshashref) = @_; my $license = $variableshashref->{'LICENSENAME'}; for ( my $i = 0; $i <= $#{$changefile}; $i++ ) { if ( ${$changefile}[$i] =~ /^\s*Copyright\s*:\s*(.+?)\s*$/ ) { ${$changefile}[$i] = "License: $license\n"; my $infoline = "Info: Replaced Copyright with License: $license !\n"; push( @installer::globals::logfileinfo, $infoline); last; } } } ######################################################### # Building relocatable Solaris packages means: # 1. Add "BASEDIR=/opt" into pkginfo # 2. Remove "/opt/" from all objects in prototype file # For step2 this function exists # Sample: d none /opt/openofficeorg20/help 0755 root other # -> d none openofficeorg20/help 0755 root other ######################################################### sub make_prototypefile_relocatable { my ($prototypefile, $relocatablepath) = @_; for ( my $i = 0; $i <= $#{$prototypefile}; $i++ ) { if ( ${$prototypefile}[$i] =~ /^\s*\w\s+\w+\s+\/\w+/ ) # this is an object line { ${$prototypefile}[$i] =~ s/$relocatablepath//; # Important: $relocatablepath has a "/" at the end. Example "/opt/" } } # If the $relocatablepath is "/opt/openoffice20/" the line "d none /opt/openoffice20" was not changed. # This line has to be removed now if ( $relocatablepath ne "/" ) { $relocatablepath =~ s/\/\s*$//; } # removing the ending slash for ( my $i = 0; $i <= $#{$prototypefile}; $i++ ) { if ( ${$prototypefile}[$i] =~ /^\s*d\s+\w+\s+\Q$relocatablepath\E/ ) { my $line = ${$prototypefile}[$i]; splice(@{$prototypefile},$i,1); # removing the line $line =~ s/\s*$//; my $infoline = "Info: Removed line \"$line\" from prototype file!\n"; push( @installer::globals::logfileinfo, $infoline); last; } } # Making "\$" to "$" in prototype file. "\$" was created by epm. for ( my $i = 0; $i <= $#{$prototypefile}; $i++ ) { if ( ${$prototypefile}[$i] =~ /\\\$/ ) { ${$prototypefile}[$i] =~ s/\\\$/\$/g; my $infoline2 = "Info: Changed line in prototype file: ${$prototypefile}[$i] !\n"; push( @installer::globals::logfileinfo, $infoline2); } } } ######################################################################### # In scp the flag VOLATEFILE can be used. This shall lead to style "v" # in Solaris prototype file. This is not supported by epm and has # therefore to be included in prototypefile, not in epm list file. ######################################################################### sub set_volatilefile_into_prototypefile { my ($prototypefile, $filesref) = @_; for ( my $i = 0; $i <= $#{$filesref}; $i++ ) { my $onefile = ${$filesref}[$i]; my $styles = ""; if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; } if ( $styles =~ /\bVOLATILEFILE\b/ ) { my $sourcepath = $onefile->{'sourcepath'}; for ( my $j = 0; $j <= $#{$prototypefile}; $j++ ) { if (( ${$prototypefile}[$j] =~ /^\s*f\s+none\s+/ ) && ( ${$prototypefile}[$j] =~ /\=\Q$sourcepath\E\s+/ )) { my $oldline = ${$prototypefile}[$j]; ${$prototypefile}[$j] =~ s/^\s*f/v/; my $newline = ${$prototypefile}[$j]; $oldline =~ s/\s*$//; $newline =~ s/\s*$//; my $infoline = "Volatile file: Changing content from \"$oldline\" to \"$newline\" .\n"; push(@installer::globals::logfileinfo, $infoline); last; } } } } } ######################################################################### # Replacing the variables in the Solaris patch shell scripts. # Taking care, that multiple slashes are not always removed. ######################################################################### sub replace_variables_in_shellscripts_for_patch { my ($scriptfile, $scriptfilename, $oldstring, $newstring) = @_; for ( my $i = 0; $i <= $#{$scriptfile}; $i++ ) { if ( ${$scriptfile}[$i] =~ /\Q$oldstring\E/ ) { my $oldline = ${$scriptfile}[$i]; if (( $oldstring eq "PRODUCTDIRECTORYNAME" ) && ( $newstring eq "" )) { $oldstring = $oldstring . "/"; } ${$scriptfile}[$i] =~ s/\Q$oldstring\E/$newstring/g; my $infoline = "Info: Substituting in $scriptfilename $oldstring by $newstring\n"; push(@installer::globals::logfileinfo, $infoline); } } } ######################################################################### # Replacing the variables in the shell scripts or in the epm list file # Linux: spec file # Solaris: preinstall, postinstall, preremove, postremove # If epm is used in the original version (not relocatable) # the variables have to be exchanged in the list file, # created for epm. ######################################################################### sub replace_variables_in_shellscripts { my ($scriptfile, $scriptfilename, $oldstring, $newstring) = @_; my $debug = 0; if ( $oldstring eq "PRODUCTDIRECTORYNAME" ) { $debug = 1; } for ( my $i = 0; $i <= $#{$scriptfile}; $i++ ) { if ( ${$scriptfile}[$i] =~ /\Q$oldstring\E/ ) { my $oldline = ${$scriptfile}[$i]; ${$scriptfile}[$i] =~ s/\Q$oldstring\E/$newstring/g; ${$scriptfile}[$i] =~ s/\/\//\//g; # replacing "//" by "/" , if path $newstring is empty! my $infoline = "Info: Substituting in $scriptfilename $oldstring by $newstring\n"; push(@installer::globals::logfileinfo, $infoline); if ( $debug ) { $infoline = "Old Line: $oldline"; push(@installer::globals::logfileinfo, $infoline); $infoline = "New Line: ${$scriptfile}[$i]"; push(@installer::globals::logfileinfo, $infoline); } } } } ############################################################ # Determinig the directory created by epm, in which the # RPMS or Solaris packages are created. ############################################################ sub determine_installdir_ooo { # A simple "ls" command returns the directory name my $dirname = ""; my $systemcall = "ls |"; open (LS, "$systemcall"); $dirname = ; close (LS); $dirname =~ s/\s*$//; my $infoline = "Info: Directory created by epm: $dirname\n"; push(@installer::globals::logfileinfo, $infoline); return $dirname; } ############################################################ # Setting the tab content into the file container ############################################################ sub set_tab_into_datafile { my ($changefile, $filesref) = @_; my @newclasses = (); my $newclassesstring = ""; if ( $installer::globals::issolarispkgbuild ) { for ( my $i = 0; $i <= $#{$filesref}; $i++ ) { my $onefile = ${$filesref}[$i]; if ( $onefile->{'SolarisClass'} ) { my $sourcepath = $onefile->{'sourcepath'}; for ( my $j = 0; $j <= $#{$changefile}; $j++ ) { if (( ${$changefile}[$j] =~ /^\s*f\s+none\s+/ ) && ( ${$changefile}[$j] =~ /\=\Q$sourcepath\E\s+/ )) { my $oldline = ${$changefile}[$j]; ${$changefile}[$j] =~ s/f\s+none/e $onefile->{'SolarisClass'}/; my $newline = ${$changefile}[$j]; $oldline =~ s/\s*$//; $newline =~ s/\s*$//; my $infoline = "TAB: Changing content from \"$oldline\" to \"$newline\" .\n"; push(@installer::globals::logfileinfo, $infoline); # collecting all new classes if (! installer::existence::exists_in_array($onefile->{'SolarisClass'}, \@newclasses)) { push(@newclasses, $onefile->{'SolarisClass'}); } last; } } } } $newclassesstring = installer::converter::convert_array_to_space_separated_string(\@newclasses); } if ( $installer::globals::islinuxrpmbuild ) { for ( my $i = 0; $i <= $#{$filesref}; $i++ ) { my $onefile = ${$filesref}[$i]; if ( $onefile->{'SpecFileContent'} ) { my $destination = $onefile->{'destination'}; for ( my $j = 0; $j <= $#{$changefile}; $j++ ) { if ( ${$changefile}[$j] =~ /^\s*(\%attr\(.*\))\s+(\".*?\Q$destination\E\"\s*)$/ ) { my $begin = $1; my $end = $2; my $oldline = ${$changefile}[$j]; ${$changefile}[$j] = $begin . " " . $onefile->{'SpecFileContent'} . " " . $end; my $newline = ${$changefile}[$j]; $oldline =~ s/\s*$//; $newline =~ s/\s*$//; my $infoline = "TAB: Changing content from \"$oldline\" to \"$newline\" .\n"; push(@installer::globals::logfileinfo, $infoline); last; } } } } } return $newclassesstring; } ############################################################ # Including additional classes into the pkginfo file ############################################################ sub include_classes_into_pkginfo { my ($changefile, $classesstring) = @_; for ( my $i = 0; $i <= $#{$changefile}; $i++ ) { if ( ${$changefile}[$i] =~ /^\s*CLASSES\=none/ ) { ${$changefile}[$i] =~ s/\s*$//; my $oldline = ${$changefile}[$i]; ${$changefile}[$i] = ${$changefile}[$i] . " " . $classesstring . "\n"; my $newline = ${$changefile}[$i]; $newline =~ s/\s*$//; my $infoline = "pkginfo file: Changing content from \"$oldline\" to \"$newline\" .\n"; push(@installer::globals::logfileinfo, $infoline); } } } ########################################################################################## # Checking, if an extension is included into the package (Linux). # All extension files have to be installed into directory # share/extension/install # %attr(0444,root,root) "/opt/staroffice8/share/extension/install/SunSearchToolbar.oxt" ########################################################################################## sub is_extension_package { my ($specfile) = @_; my $is_extension_package = 0; for ( my $i = 0; $i <= $#{$specfile}; $i++ ) { my $line = ${$specfile}[$i]; if ( $line =~ /share\/extension\/install\/.*?\.oxt\"\s*$/ ) { $is_extension_package = 1; last; } } return $is_extension_package; } ###################################################################### # Checking, if an extension is included into the package (Solaris). # All extension files have to be installed into directory # share/extension/install ###################################################################### sub get_extension_name { my ($prototypefile) = @_; my $extensionName = ""; for ( my $i = 0; $i <= $#{$prototypefile}; $i++ ) { my $line = ${$prototypefile}[$i]; if ( $line =~ /^\s*f\s+none\s+share\/extension\/install\/(\w+?\.oxt)\s*\=/ ) { $extensionName = $1; last; } } return $extensionName; } ############################################################ # A Solaris patch contains 7 specific scripts ############################################################ sub add_scripts_into_prototypefile { my ($prototypefile, $prototypefilename, $languagestringref, $staticpath) = @_; # The files are stored in the directory $installer::globals::patchincludepath # The file names are available via @installer::globals::solarispatchscripts my $path = $installer::globals::patchincludepath; $path =~ s/\/\s*$//; $path = $path . $installer::globals::separator; my @newlines = (); my $extensionname = get_extension_name($prototypefile); if ( $extensionname ne "" ) { for ( my $i = 0; $i <= $#installer::globals::solarispatchscriptsforextensions; $i++ ) { my $sourcefilename = $path . $installer::globals::solarispatchscriptsforextensions[$i]; my $destfile = $installer::globals::solarispatchscriptsforextensions[$i]; # If the sourcepath has "_extension" in its name, this has to be removed $destfile =~ s/_extensions\s*$//; # hard coded renaming of script name # Creating unique directory name with $prototypefilename my $extensiondir = installer::systemactions::create_directories("extensionscripts", $languagestringref); if ( $prototypefilename =~ /\/(\S*?)\s*$/ ) { $prototypefilename = $1; } $prototypefilename =~ s/\./_/g; my $destdir = $extensiondir . $installer::globals::separator . $prototypefilename; if ( ! -d $destdir ) { installer::systemactions::create_directory($destdir); } my $destpath = $destdir . $installer::globals::separator . $destfile; if ( -f $destpath ) { unlink($destpath); } # Reading file my $scriptfile = installer::files::read_file($sourcefilename); # Replacing variables my $oldstring = "\$\{OXTFILENAME\}"; replace_variables_in_shellscripts_for_patch($scriptfile, $destpath, $oldstring, $extensionname); $oldstring = "PRODUCTDIRECTORYNAME"; replace_variables_in_shellscripts_for_patch($scriptfile, $destpath, $oldstring, $staticpath); # Saving file installer::files::save_file($destpath, $scriptfile); # Writing file destination into prototype file my $line = "i $destfile=" . $destpath . "\n"; push(@newlines, $line); } } else { for ( my $i = 0; $i <= $#installer::globals::solarispatchscripts; $i++ ) { my $line = "i $installer::globals::solarispatchscripts[$i]=" . $path . $installer::globals::solarispatchscripts[$i] . "\n"; push(@newlines, $line); } } # Including the new lines after the last line starting with "i" for ( my $i = 0; $i <= $#{$prototypefile}; $i++ ) { if ( ${$prototypefile}[$i] =~ /^\s*i\s+copyright/ ) { splice(@{$prototypefile}, $i, 1); # ignoring old copyright text, using patch standard next; } if ( ${$prototypefile}[$i] =~ /^\s*i\s+/ ) { next; } splice(@{$prototypefile}, $i, 0, @newlines); last; } } ############################################################ # Adding patch infos in pkginfo file ############################################################ sub include_patchinfos_into_pkginfo { my ( $changefile, $filename, $variableshashref ) = @_; # SUNW_PATCHID=101998-10 # SUNW_OBSOLETES=114999-01 113999-01 # SUNW_PKGTYPE=usr # SUNW_PKGVERS=1.0 # SUNW_REQUIRES=126411-01 my $patchidname = "SOLSPARCPATCHID"; if ( $installer::globals::issolarisx86build ) { $patchidname = "SOLIAPATCHID"; } if ( ! $variableshashref->{$patchidname} ) { installer::exiter::exit_program("ERROR: Variable $patchidname not defined in zip list file!", "include_patchinfos_into_pkginfo"); } my $newline = "SUNW_PATCHID=" . $variableshashref->{$patchidname} . "\n"; add_one_line_into_file($changefile, $newline, $filename); my $patchobsoletesname = "SOLSPARCPATCHOBSOLETES"; if ( $installer::globals::issolarisx86build ) { $patchobsoletesname = "SOLIAPATCHOBSOLETES"; } my $obsoletes = ""; if ( $variableshashref->{$patchobsoletesname} ) { $obsoletes = $variableshashref->{$patchobsoletesname}; } $newline = "SUNW_OBSOLETES=" . $obsoletes . "\n"; add_one_line_into_file($changefile, $newline, $filename); my $patchrequiresname = "SOLSPARCPATCHREQUIRES"; if ( $installer::globals::issolarisx86build ) { $patchrequiresname = "SOLIAPATCHREQUIRES"; } if ( $variableshashref->{$patchrequiresname} ) { my $requires = $variableshashref->{$patchrequiresname}; $newline = "SUNW_REQUIRES=" . $requires . "\n"; add_one_line_into_file($changefile, $newline, $filename); } $newline = "SUNW_PATCH_PROPERTIES=\n"; add_one_line_into_file($changefile, $newline, $filename); # $newline = "SUNW_PKGTYPE=usr\n"; # add_one_line_into_file($changefile, $newline, $filename); # $newline = "SUNW_PKGVERS=1.0\n"; # add_one_line_into_file($changefile, $newline, $filename); } ############################################################ # Setting the correct Solaris locales ############################################################ sub get_solaris_language_for_langpack { my ( $onelanguage ) = @_; my $sollanguage = $onelanguage; $sollanguage =~ s/\-/\_/; if ( $sollanguage eq "de" ) { $sollanguage = "de"; } elsif ( $sollanguage eq "es" ) { $sollanguage = "es"; } elsif ( $sollanguage eq "fr" ) { $sollanguage = "fr"; } elsif ( $sollanguage eq "it" ) { $sollanguage = "it"; } elsif ( $sollanguage eq "sv" ) { $sollanguage = "sv"; } elsif ( $sollanguage eq "pt_BR" ) { $sollanguage = "pt_BR"; } elsif ( $sollanguage eq "ja" ) { $sollanguage = "ja,ja_JP,ja_JP.PCK,ja_JP.UTF-8"; } elsif ( $sollanguage eq "ko" ) { $sollanguage = "ko,ko.UTF-8"; } elsif ( $sollanguage eq "zh_CN" ) { $sollanguage = "zh,zh.GBK,zh_CN,zh_CN.GB18030,zh.UTF-8"; } elsif ( $sollanguage eq "zh_TW" ) { $sollanguage = "zh_TW,zh_TW.BIG5,zh_TW.UTF-8,zh_HK.BIG5HK,zh_HK.UTF-8"; } return $sollanguage; } ############################################################ # Adding language infos in pkginfo file ############################################################ sub include_languageinfos_into_pkginfo { my ( $changefile, $filename, $languagestringref, $onepackage, $variableshashref ) = @_; # SUNWPKG_LIST=core01 # SUNW_LOC=de my $solarislanguage = get_solaris_language_for_langpack($$languagestringref); my $newline = "SUNW_LOC=" . $solarislanguage . "\n"; add_one_line_into_file($changefile, $newline, $filename); if ( $onepackage->{'pkg_list_entry'} ) { my $packagelistentry = $onepackage->{'pkg_list_entry'}; installer::packagelist::resolve_packagevariables(\$packagelistentry, $variableshashref, 1); $newline = "SUNW_PKGLIST=" . $packagelistentry . "\n"; add_one_line_into_file($changefile, $newline, $filename); } } ############################################################ # Collecting all files included in patch in # @installer::globals::patchfilecollector ############################################################ sub collect_patch_files { my ($file, $packagename, $prefix) = @_; # $file is the spec file or the prototypefile $prefix = $prefix . "/"; my $packagenamestring = "Package " . $packagename . " \:\n"; push(@installer::globals::patchfilecollector, $packagenamestring); for ( my $i = 0; $i <= $#{$file}; $i++ ) { my $line = ${$file}[$i]; if ( $installer::globals::islinuxrpmbuild ) { # %attr(0444,root,root) "/opt/openofficeorg20/program/about.bmp" if ( $line =~ /^\s*\%attr\(.*\)\s*\"(.*?)\"\s*$/ ) { my $filename = $1 . "\n"; $filename =~ s/^\s*\Q$prefix\E//; push(@installer::globals::patchfilecollector, $filename); } } if ( $installer::globals::issolarispkgbuild ) { # f none program/msomrl.rdb=/ab/SRC680/unxsols4.pro/bin/msomrl.rdb 0444 root bin if ( $line =~ /^\s*f\s+\w+\s+(.*?)\=/ ) { my $filename = $1 . "\n"; push(@installer::globals::patchfilecollector, $filename); } } } push(@installer::globals::patchfilecollector, "\n"); } ############################################################ # Including package names into the depend files. # The package names have to be included into # packagelist. They are already saved in # %installer::globals::dependfilenames. ############################################################ sub put_packagenames_into_dependfile { my ( $file ) = @_; for ( my $i = 0; $i <= $#{$file}; $i++ ) { my $line = ${$file}[$i]; if ( $line =~ /^\s*\w\s+(.*?)\s*$/ ) { my $abbreviation = $1; if ( exists($installer::globals::dependfilenames{$abbreviation}) ) { $line =~ s/\s*$//; ${$file}[$i] = $line . "\t" . $installer::globals::dependfilenames{$abbreviation} . "\n"; } } } } ############################################################ # Including the relocatable directory into # spec file and pkginfo file # Linux: set topdir in specfile # Solaris: remove $relocatablepath (/opt/) # for all objects in prototype file # and changing "topdir" for Linux ############################################################ sub prepare_packages { my ($loggingdir, $packagename, $staticpath, $relocatablepath, $onepackage, $variableshashref, $filesref, $languagestringref) = @_; my $filename = ""; my $newline = ""; my $newepmdir = $installer::globals::epmoutpath . $installer::globals::separator; my $localrelocatablepath = $relocatablepath; if ( $localrelocatablepath ne "/" ) { $localrelocatablepath =~ s/\/\s*$//; } if ( $installer::globals::issolarispkgbuild ) { $filename = $packagename . ".pkginfo"; $newline = "BASEDIR\=" . $localrelocatablepath . "\n"; } if ( $installer::globals::islinuxrpmbuild ) { # if ( $localrelocatablepath =~ /^\s*$/ ) { $localrelocatablepath = "/"; }; # at least the "/" $filename = $packagename . ".spec"; $newline = "Prefix\:\ " . $localrelocatablepath . "\n"; } my $completefilename = $newepmdir . $filename; if ( ! -f $completefilename) { installer::exiter::exit_program("ERROR: Did not find file: $completefilename", "prepare_packages"); } my $changefile = installer::files::read_file($completefilename); if ( $newline ne "" ) { add_one_line_into_file($changefile, $newline, $filename); installer::files::save_file($completefilename, $changefile); } # my $newepmdir = $completefilename; # installer::pathanalyzer::get_path_from_fullqualifiedname(\$newepmdir); # adding new "topdir" and removing old "topdir" in specfile if ( $installer::globals::islinuxrpmbuild ) { set_topdir_in_specfile($changefile, $filename, $newepmdir); set_autoprovreq_in_specfile($changefile, $onepackage->{'findrequires'}, "$installer::globals::unpackpath" . "/bin"); set_packager_in_specfile($changefile); if ( is_extension_package($changefile) ) { set_prereq_in_specfile($changefile); } set_license_in_specfile($changefile, $variableshashref); set_tab_into_datafile($changefile, $filesref); # check_requirements_in_specfile($changefile); installer::files::save_file($completefilename, $changefile); if ( $installer::globals::patch ) { collect_patch_files($changefile, $packagename, $localrelocatablepath); } } # removing the relocatable path in prototype file if ( $installer::globals::issolarispkgbuild ) { set_revision_in_pkginfo($changefile, $filename, $variableshashref); set_maxinst_in_pkginfo($changefile, $filename); set_solaris_parameter_in_pkginfo($changefile, $filename, $variableshashref); if ( $installer::globals::issolarisx86build ) { fix_architecture_setting($changefile); } if ( ! $installer::globals::patch ) { set_patchlist_in_pkginfo_for_respin($changefile, $filename, $variableshashref, $packagename); } if ( $installer::globals::patch ) { include_patchinfos_into_pkginfo($changefile, $filename, $variableshashref); } if ( $installer::globals::languagepack ) { include_languageinfos_into_pkginfo($changefile, $filename, $languagestringref, $onepackage, $variableshashref); } installer::files::save_file($completefilename, $changefile); my $prototypefilename = $packagename . ".prototype"; $prototypefilename = $newepmdir . $prototypefilename; if (! -f $prototypefilename) { installer::exiter::exit_program("ERROR: Did not find prototype file: $prototypefilename", "prepare_packages"); } my $prototypefile = installer::files::read_file($prototypefilename); make_prototypefile_relocatable($prototypefile, $relocatablepath); set_volatilefile_into_prototypefile($prototypefile, $filesref); my $classesstring = set_tab_into_datafile($prototypefile, $filesref); if ($classesstring) { include_classes_into_pkginfo($changefile, $classesstring); installer::files::save_file($completefilename, $changefile); } if ( $installer::globals::patch ) { add_scripts_into_prototypefile($prototypefile, $prototypefilename, $languagestringref, $staticpath); } installer::files::save_file($prototypefilename, $prototypefile); if ( $installer::globals::patch ) { collect_patch_files($prototypefile, $packagename, ""); } # Adding package names into depend files for Solaris (not supported by epm) my $dependfilename = $packagename . ".depend"; $dependfilename = $newepmdir . $dependfilename; if ( -f $dependfilename) { my $dependfile = installer::files::read_file($dependfilename); put_packagenames_into_dependfile($dependfile); installer::files::save_file($dependfilename, $dependfile); } } return $newepmdir; } ############################################################ # Linux requirement for perl is changed by epm from # /usr/bin/perl to perl . # Requires: perl ############################################################ sub check_requirements_in_specfile { my ( $specfile ) = @_; for ( my $i = 0; $i <= $#{$specfile}; $i++ ) { if (( ${$specfile}[$i] =~ /^\s*Requires/ ) && ( ${$specfile}[$i] =~ /\bperl\b/ ) && ( ! ( ${$specfile}[$i] =~ /\/usr\/bin\/perl\b/ ))) { my $oldline = ${$specfile}[$i]; ${$specfile}[$i] =~ s/perl/\/usr\/bin\/perl/; my $newline = ${$specfile}[$i]; $oldline =~ s/\s*$//; $newline =~ s/\s*$//; my $infoline = "Spec File: Changing content from \"$oldline\" to \"$newline\".\n"; push(@installer::globals::logfileinfo, $infoline); } } } ############################################################################### # Replacement of PRODUCTINSTALLLOCATION and PRODUCTDIRECTORYNAME in the # epm list file. # The complete rootpath is stored in $installer::globals::rootpath # or for each package in $onepackage->{'destpath'} # The static rootpath is stored in $staticpath # The relocatable path is stored in $relocatablepath # PRODUCTINSTALLLOCATION is the relocatable part ("/opt") and # PRODUCTDIRECTORYNAME the static path ("openofficeorg20"). # In standard epm process: # No usage of package specific variables like $BASEDIR, because # 1. These variables would be replaced in epm process # 2. epm version 3.7 does not support relocatable packages ############################################################################### sub resolve_path_in_epm_list_before_packaging { my ($listfile, $listfilename, $variable, $path) = @_; installer::logger::include_header_into_logfile("Replacing variables in epm list file:"); $path =~ s/\/\s*$//; replace_variables_in_shellscripts($listfile, $listfilename, $variable, $path); } ################################################################# # Determining the rpm version. Beginning with rpm version 4.0 # the tool to create RPMs is "rpmbuild" and no longer "rpm" ################################################################# sub determine_rpm_version { my $rpmversion = 0; my $rpmout = ""; my $systemcall = "rpm --version |"; open (RPM, "$systemcall"); $rpmout = ; close (RPM); $rpmout =~ s/\s*$//g; my $infoline = "Systemcall: $systemcall\n"; push( @installer::globals::logfileinfo, $infoline); if ( $rpmout eq "" ) { $infoline = "ERROR: Could not find file \"rpm\" !\n"; } else { $infoline = "Success: rpm version: $rpmout\n"; } push( @installer::globals::logfileinfo, $infoline); if ( $rpmout =~ /(\d+)\.(\d+)\.(\d+)/ ) { $rpmversion = $1; } elsif ( $rpmout =~ /(\d+)\.(\d+)/ ) { $rpmversion = $1; } elsif ( $rpmout =~ /(\d+)/ ) { $rpmversion = $1; } else { installer::exiter::exit_program("ERROR: Unknown format: $rpmout ! Expected: \"a.b.c\", or \"a.b\", or \"a\"", "determine_rpm_version"); } return $rpmversion; } ################################################# # Systemcall to start the packaging process ################################################# sub create_packages_without_epm { my ($epmdir, $packagename, $includepatharrayref, $allvariables, $languagestringref) = @_; # Solaris: pkgmk -o -f solaris-2.8-sparc/SUNWso8m34.prototype -d solaris-2.8-sparc # Solaris: pkgtrans solaris-2.8-sparc SUNWso8m34.pkg SUNWso8m34 # Solaris: tar -cf - SUNWso8m34 | gzip > SUNWso8m34.tar.gz if ( $installer::globals::issolarispkgbuild ) { my $prototypefile = $epmdir . $packagename . ".prototype"; if (! -f $prototypefile) { installer::exiter::exit_program("ERROR: Did not find file: $prototypefile", "create_packages_without_epm"); } my $destinationdir = $prototypefile; installer::pathanalyzer::get_path_from_fullqualifiedname(\$destinationdir); $destinationdir =~ s/\/\s*$//; # removing ending slashes # my $systemcall = "pkgmk -o -f $prototypefile -d $destinationdir \> /dev/null 2\>\&1"; my $systemcall = "pkgmk -o -f $prototypefile -d $destinationdir 2\>\&1 |"; installer::logger::print_message( "... $systemcall ...\n" ); my $maxpkgmkcalls = 3; for ( my $i = 1; $i <= $maxpkgmkcalls; $i++ ) { my @pkgmkoutput = (); open (PKGMK, "$systemcall"); while () {push(@pkgmkoutput, $_); } close (PKGMK); my $returnvalue = $?; # $? contains the return value of the systemcall my $infoline = "Systemcall (Try $i): $systemcall\n"; push( @installer::globals::logfileinfo, $infoline); for ( my $j = 0; $j <= $#pkgmkoutput; $j++ ) { if ( $i < $maxpkgmkcalls ) { $pkgmkoutput[$j] =~ s/\bERROR\b/PROBLEM/ig; } push( @installer::globals::logfileinfo, "$pkgmkoutput[$j]"); } if ($returnvalue) { $infoline = "Try $i : Could not execute \"$systemcall\"!\n"; push( @installer::globals::logfileinfo, $infoline); if ( $i == $maxpkgmkcalls ) { installer::exiter::exit_program("ERROR: \"$systemcall\"!", "create_packages_without_epm"); } } else { installer::logger::print_message( "Success (Try $i): \"$systemcall\"\n" ); $infoline = "Success: Executed \"$systemcall\" successfully!\n"; push( @installer::globals::logfileinfo, $infoline); last; } } # It might be necessary to save uncompressed Solaris packages if ( $allvariables->{'JDSBUILD'} ) { if ( ! $installer::globals::jds_language_controlled ) { my $correct_language = installer::worker::check_jds_language($allvariables, $languagestringref); $installer::globals::correct_jds_language = $correct_language; $installer::globals::jds_language_controlled = 1; } if ( $installer::globals::correct_jds_language ) { if ( $installer::globals::saved_packages_path eq "" ) { $packagestempdir = installer::systemactions::create_directories("jds", $languagestringref); $installer::globals::saved_packages_path = $packagestempdir; push(@installer::globals::jdsremovedirs, $packagestempdir); } $systemcall = "cd $destinationdir; cp -p -R $packagename $installer::globals::saved_packages_path;"; make_systemcall($systemcall); installer::logger::print_message( "... $systemcall ...\n" ); # Setting unix rights to "775" for all created directories inside the package, # that is saved in temp directory $systemcall = "cd $packagestempdir; find $packagename -type d -exec chmod 775 \{\} \\\;"; installer::logger::print_message( "... $systemcall ...\n" ); $returnvalue = system($systemcall); $infoline = "Systemcall: $systemcall\n"; push( @installer::globals::logfileinfo, $infoline); if ($returnvalue) { $infoline = "ERROR: Could not execute \"$systemcall\"!\n"; push( @installer::globals::logfileinfo, $infoline); } else { $infoline = "Success: Executed \"$systemcall\" successfully!\n"; push( @installer::globals::logfileinfo, $infoline); } } } # compressing packages my $faspac = "faspac-so.sh"; my $compressorref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$faspac, $includepatharrayref, 0); if ($$compressorref ne "") { # Saving original pkginfo, to set time stamp later my $pkginfoorig = "$destinationdir/$packagename/pkginfo"; my $pkginfotmp = "$destinationdir/$packagename" . ".pkginfo.tmp"; $systemcall = "cp -p $pkginfoorig $pkginfotmp"; make_systemcall($systemcall); $faspac = $$compressorref; $infoline = "Found compressor: $faspac\n"; push( @installer::globals::logfileinfo, $infoline); installer::logger::print_message( "... $faspac ...\n" ); installer::logger::include_timestamp_into_logfile("Starting $faspac"); $systemcall = "/bin/sh $faspac -a -q -d $destinationdir $packagename"; # $faspac has to be the absolute path! make_systemcall($systemcall); # Setting time stamp for pkginfo, because faspac-so.sh changed the pkginfo file, # updated the size and checksum, but not the time stamp. $systemcall = "touch -r $pkginfotmp $pkginfoorig"; make_systemcall($systemcall); if ( -f $pkginfotmp ) { unlink($pkginfotmp); } installer::logger::include_timestamp_into_logfile("End of $faspac"); } else { $infoline = "Not found: $faspac\n"; push( @installer::globals::logfileinfo, $infoline); } # Setting unix rights to "775" for all created directories inside the package $systemcall = "cd $destinationdir; find $packagename -type d -exec chmod 775 \{\} \\\;"; installer::logger::print_message( "... $systemcall ...\n" ); $returnvalue = system($systemcall); $infoline = "Systemcall: $systemcall\n"; push( @installer::globals::logfileinfo, $infoline); if ($returnvalue) { $infoline = "ERROR: Could not execute \"$systemcall\"!\n"; push( @installer::globals::logfileinfo, $infoline); } else { $infoline = "Success: Executed \"$systemcall\" successfully!\n"; push( @installer::globals::logfileinfo, $infoline); } ###################### # making pkg files ###################### # my $streamname = $packagename . ".pkg"; # $systemcall = "pkgtrans $destinationdir $streamname $packagename"; # print "... $systemcall ...\n"; # $returnvalue = system($systemcall); # $infoline = "Systemcall: $systemcall\n"; # push( @installer::globals::logfileinfo, $infoline); # if ($returnvalue) # { # $infoline = "ERROR: Could not execute \"$systemcall\"!\n"; # push( @installer::globals::logfileinfo, $infoline); # } # else # { # $infoline = "Success: Executed \"$systemcall\" successfully!\n"; # push( @installer::globals::logfileinfo, $infoline); # } ######################### # making tar.gz files ######################### # my $targzname = $packagename . ".tar.gz"; # $systemcall = "cd $destinationdir; tar -cf - $packagename | gzip > $targzname"; # print "... $systemcall ...\n"; # $returnvalue = system($systemcall); # $infoline = "Systemcall: $systemcall\n"; # push( @installer::globals::logfileinfo, $infoline); # if ($returnvalue) # { # $infoline = "ERROR: Could not execute \"$systemcall\"!\n"; # push( @installer::globals::logfileinfo, $infoline); # } # else # { # $infoline = "Success: Executed \"$systemcall\" successfully!\n"; # push( @installer::globals::logfileinfo, $infoline); # } } # Linux: rpm -bb so8m35.spec ( -> dependency check abklemmen? ) if ( $installer::globals::islinuxrpmbuild ) { my $specfilename = $epmdir . $packagename . ".spec"; if (! -f $specfilename) { installer::exiter::exit_program("ERROR: Did not find file: $specfilename", "create_packages_without_epm"); } my $rpmcommand = "rpm"; my $rpmversion = determine_rpm_version(); if ( $rpmversion >= 4 ) { $rpmcommand = "rpmbuild"; } # saving globally for later usage $installer::globals::rpmcommand = $rpmcommand; $installer::globals::rpmquerycommand = "rpm"; # For queries "rpm" is used, not "rpmbuild" my $target = ""; if ( $installer::globals::compiler =~ /unxlngi/) { $target = "i586"; } elsif ( $installer::globals::compiler =~ /unxlng/) {$target = (POSIX::uname())[4]; } my $systemcall = "$rpmcommand -bb $specfilename --target $target 2\>\&1 |"; installer::logger::print_message( "... $systemcall ...\n" ); my $maxrpmcalls = 3; for ( my $i = 1; $i <= $maxrpmcalls; $i++ ) { my @rpmoutput = (); open (RPM, "$systemcall"); while () {push(@rpmoutput, $_); } close (RPM); my $returnvalue = $?; # $? contains the return value of the systemcall my $infoline = "Systemcall (Try $i): $systemcall\n"; push( @installer::globals::logfileinfo, $infoline); for ( my $j = 0; $j <= $#rpmoutput; $j++ ) { if ( $i < $maxrpmcalls ) { $rpmoutput[$j] =~ s/\bERROR\b/PROBLEM/ig; } push( @installer::globals::logfileinfo, "$rpmoutput[$j]"); } if ($returnvalue) { $infoline = "Try $i : Could not execute \"$systemcall\"!\n"; push( @installer::globals::logfileinfo, $infoline); if ( $i == $maxrpmcalls ) { installer::exiter::exit_program("ERROR: \"$systemcall\"!", "create_packages_without_epm"); } } else { installer::logger::print_message( "Success (Try $i): \"$systemcall\"\n" ); $infoline = "Success: Executed \"$systemcall\" successfully!\n"; push( @installer::globals::logfileinfo, $infoline); last; } } } } ################################################# # Removing all temporary files created by epm ################################################# sub remove_temporary_epm_files { my ($epmdir, $loggingdir, $packagename) = @_; # saving the files into the loggingdir if ( $installer::globals::issolarispkgbuild ) { my @extensions = (); push(@extensions, ".pkginfo"); push(@extensions, ".prototype"); push(@extensions, ".postinstall"); push(@extensions, ".postremove"); push(@extensions, ".preinstall"); push(@extensions, ".preremove"); push(@extensions, ".depend"); for ( my $i = 0; $i <= $#extensions; $i++ ) { my $removefile = $epmdir . $packagename . $extensions[$i]; my $destfile = $loggingdir . $packagename . $extensions[$i] . ".log"; if (! -f $removefile) { next; } my $systemcall = "mv -f $removefile $destfile"; system($systemcall); # ignoring the return value $infoline = "Systemcall: $systemcall\n"; push( @installer::globals::logfileinfo, $infoline); } # removing the package # my $removedir = $epmdir . $packagename; # # my $systemcall = "rm -rf $removedir"; # # print "... $systemcall ...\n"; # # my $returnvalue = system($systemcall); # # my $infoline = "Systemcall: $systemcall\n"; # push( @installer::globals::logfileinfo, $infoline); # # if ($returnvalue) # { # $infoline = "ERROR: Could not execute \"$systemcall\"!\n"; # push( @installer::globals::logfileinfo, $infoline); # } # else # { # $infoline = "Success: Executed \"$systemcall\" successfully!\n"; # push( @installer::globals::logfileinfo, $infoline); # } } if ( $installer::globals::islinuxrpmbuild ) { my $removefile = $epmdir . $packagename . ".spec"; my $destfile = $loggingdir . $packagename . ".spec.log"; # if (! -f $removefile) { next; } my $systemcall = "mv -f $removefile $destfile"; system($systemcall); # ignoring the return value $infoline = "Systemcall: $systemcall\n"; push( @installer::globals::logfileinfo, $infoline); # removing the directory "buildroot" my $removedir = $epmdir . "buildroot"; $systemcall = "rm -rf $removedir"; installer::logger::print_message( "... $systemcall ...\n" ); my $returnvalue = system($systemcall); my $infoline = "Systemcall: $systemcall\n"; push( @installer::globals::logfileinfo, $infoline); if ($returnvalue) { $infoline = "ERROR: Could not execute \"$systemcall\"!\n"; push( @installer::globals::logfileinfo, $infoline); } else { $infoline = "Success: Executed \"$systemcall\" successfully!\n"; push( @installer::globals::logfileinfo, $infoline); } } } ###################################################### # Making the systemcall ###################################################### sub make_systemcall { my ($systemcall) = @_; my $returnvalue = system($systemcall); my $infoline = "Systemcall: $systemcall\n"; push( @installer::globals::logfileinfo, $infoline); if ($returnvalue) { $infoline = "ERROR: Could not execute \"$systemcall\"!\n"; push( @installer::globals::logfileinfo, $infoline); } else { $infoline = "Success: Executed \"$systemcall\" successfully!\n"; push( @installer::globals::logfileinfo, $infoline); } } ########################################################### # Creating a better directory structure in the solver. ########################################################### sub create_new_directory_structure { my ($newepmdir) = @_; my $newdir = $installer::globals::epmoutpath; if ( $installer::globals::islinuxrpmbuild ) { my $rpmdir; my $machine = ""; if ( $installer::globals::compiler =~ /unxlngi/) { $rpmdir = "$installer::globals::epmoutpath/RPMS/i586"; } elsif ( $installer::globals::compiler =~ /unxlng/) { $machine = (POSIX::uname())[4]; $rpmdir = "$installer::globals::epmoutpath/RPMS/$machine"; } else { installer::exiter::exit_program("ERROR: rpmdir undefined !", "create_new_directory_structure"); } my $systemcall = "mv $rpmdir/* $newdir"; # moving the rpms into the directory "RPMS" my $returnvalue = system($systemcall); my $infoline = "Systemcall: $systemcall\n"; push( @installer::globals::logfileinfo, $infoline); if ($returnvalue) { $infoline = "ERROR: Could not move content of \"$rpmdir\" to \"$newdir\"!\n"; push( @installer::globals::logfileinfo, $infoline); } else { $infoline = "Success: Moved content of \"$rpmdir\" to \"$newdir\"!\n"; push( @installer::globals::logfileinfo, $infoline); } # and removing the empty directory if ( $machine ne "" ) { installer::systemactions::remove_empty_directory("$installer::globals::epmoutpath/RPMS/$machine"); } installer::systemactions::remove_empty_directory("$installer::globals::epmoutpath/RPMS/i586"); installer::systemactions::remove_empty_directory("$installer::globals::epmoutpath/RPMS/i386"); installer::systemactions::remove_empty_directory("$installer::globals::epmoutpath/RPMS"); } # Setting unix rights to "775" for $newdir ("RPMS" or "packages") my $localcall = "chmod 775 $newdir \>\/dev\/null 2\>\&1"; my $callreturnvalue = system($localcall); my $callinfoline = "Systemcall: $localcall\n"; push( @installer::globals::logfileinfo, $callinfoline); if ($callreturnvalue) { $callinfoline = "ERROR: Could not execute \"$localcall\"!\n"; push( @installer::globals::logfileinfo, $callinfoline); } else { $callinfoline = "Success: Executed \"$localcall\" successfully!\n"; push( @installer::globals::logfileinfo, $callinfoline); } return $newdir; } ###################################################### # Collect modules with product specific styles. ###################################################### sub collect_modules_with_style { my ($style, $modulesarrayref) = @_; my @allmodules = (); for ( my $i = 0; $i <= $#{$modulesarrayref}; $i++ ) { my $onemodule = ${$modulesarrayref}[$i]; my $styles = ""; if ( $onemodule->{'Styles'} ) { $styles = $onemodule->{'Styles'}; } if ( $styles =~ /\b\Q$style\E\b/ ) { push(@allmodules, $onemodule); } } return \@allmodules; } ###################################################### # Remove modules without packagecontent. ###################################################### sub remove_modules_without_package { my ($allmodules) = @_; my @allmodules = (); for ( my $i = 0; $i <= $#{$allmodules}; $i++ ) { my $onemodule = ${$allmodules}[$i]; my $packagename = ""; if ( $onemodule->{'PackageName'} ) { $packagename = $onemodule->{'PackageName'}; } if ( $packagename ne "" ) { push(@allmodules, $onemodule); } } return \@allmodules; } ###################################################### # Unpacking tar.gz file and setting new packagename. ###################################################### sub unpack_tar_gz_file { my ($packagename, $destdir) = @_; my $newpackagename = ""; if ( $packagename =~ /\.tar\.gz\s*$/ ) { # Collecting all packages in directory "packages" my $oldcontent = installer::systemactions::read_directory($destdir); # unpacking gunzip my $systemcall = "cd $destdir; cat $packagename | gunzip | tar -xf -"; make_systemcall($systemcall); # deleting the tar.gz files $systemcall = "cd $destdir; rm -f $packagename"; make_systemcall($systemcall); # Finding new content -> that is the package name my ($newcontent, $allcontent ) = installer::systemactions::find_new_content_in_directory($destdir, $oldcontent); $newpackagename = ${$newcontent}[0]; installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$newpackagename); } if ( $newpackagename ne "" ) { $packagename = $newpackagename; } return $packagename; } ###################################################### # Copying files of child projects. ###################################################### sub copy_childproject_files { my ($allmodules, $sopackpath, $destdir, $modulesarrayref, $allvariables, $subdir, $includepatharrayref, $use_sopackpath) = @_; for ( my $i = 0; $i <= $#{$allmodules}; $i++ ) { my $localdestdir = $destdir; my $onemodule = ${$allmodules}[$i]; my $packagename = $onemodule->{'PackageName'}; my $sourcefile = ""; if ( $use_sopackpath ) { $sourcefile = $sopackpath . $installer::globals::separator . $installer::globals::compiler . $installer::globals::separator . $subdir . $installer::globals::separator . $packagename; } else { my $sourcepathref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$packagename, $includepatharrayref, 1); $sourcefile = $$sourcepathref; } if ( ! -f $sourcefile ) { installer::exiter::exit_program("ERROR: File not found: $sourcefile ($packagename) !", "copy_childproject_files"); } if ( $onemodule->{'Subdir'} ) { $localdestdir = $localdestdir . $installer::globals::separator . $onemodule->{'Subdir'}; if ( ! -d $localdestdir ) { installer::systemactions::create_directory($localdestdir); } } installer::systemactions::copy_one_file($sourcefile, $localdestdir); # Solaris: unpacking tar.gz files and setting new packagename if ( $installer::globals::issolarispkgbuild ) { $packagename = unpack_tar_gz_file($packagename, $localdestdir); } if (( $installer::globals::isxpdplatform ) && ( $allvariables->{'XPDINSTALLER'} )) { installer::xpdinstaller::create_xpd_file_for_childproject($onemodule, $localdestdir, $packagename, $allvariableshashref, $modulesarrayref); } } } ###################################################### # Copying files for system integration. ###################################################### sub copy_and_unpack_tar_gz_files { my ($sourcefile, $destdir) = @_; my $systemcall = "cd $destdir; cat $sourcefile | gunzip | tar -xf -"; make_systemcall($systemcall); } ###################################################### # Including child packages into the # installation set. ###################################################### sub put_childprojects_into_installset { my ($newdir, $allvariables, $modulesarrayref, $includepatharrayref) = @_; my $infoline = ""; my $sopackpath = ""; if ( $ENV{'SO_PACK'} ) { $sopackpath = $ENV{'SO_PACK'}; } else { installer::exiter::exit_program("ERROR: Environment variable SO_PACK not set!", "put_childprojects_into_installset"); } my $destdir = "$newdir"; # adding Java my $sourcefile = ""; # Finding the modules defined in scp (with flag JAVAMODULE, ADAMODULE, ...) # Getting name of package from scp-Module # Copy file into installation set # Create xpd file and put it into xpd directory # xpd file has to be created completely from module and package itself (-> no packagelist!) if ( $allvariables->{'JAVAPRODUCT'} ) { # Collect all modules with flag "JAVAMODULE" my $allmodules = collect_modules_with_style("JAVAMODULE", $modulesarrayref); $allmodules = remove_modules_without_package($allmodules); copy_childproject_files($allmodules, $sopackpath, $destdir, $modulesarrayref, $allvariables, "jre", $includepatharrayref, 1); } # Adding additional required packages (freetype). # This package names are stored in global array @installer::globals::requiredpackages if ( $allvariables->{'ADDREQUIREDPACKAGES'} ) { # Collect all modules with flag "REQUIREDPACKAGEMODULE" my $allmodules = collect_modules_with_style("REQUIREDPACKAGEMODULE", $modulesarrayref); $allmodules = remove_modules_without_package($allmodules); copy_childproject_files($allmodules, $sopackpath, $destdir, $modulesarrayref, $allvariables, "requiredpackages", $includepatharrayref, 1); } # Collect all modules with flag "USERLANDMODULE" my $alluserlandmodules = collect_modules_with_style("USERLANDMODULE", $modulesarrayref); $alluserlandmodules = remove_modules_without_package($alluserlandmodules); copy_childproject_files($alluserlandmodules, $sopackpath, $destdir, $modulesarrayref, $allvariables, "", $includepatharrayref, 0); } ###################################################### # Checking whether the new content is a directory and # not a package. If it is a directory, the complete # content of the directory has to be added to the # array newcontent. ###################################################### sub control_subdirectories { my ($content, $subdir) = @_; my @newcontent = (); for ( my $i = 0; $i <= $#{$content}; $i++ ) { if ( -d ${$content}[$i] ) { $subdir = ${$content}[$i]; installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$subdir); my $allpackages = installer::systemactions::read_directory(${$content}[$i]); for ( my $j = 0; $j <= $#{$allpackages}; $j++ ) { # Currently only Linux rpm is supported, debian packages cannot be installed via xpd installer if (( $installer::globals::islinuxbuild ) && ( ! ( ${$allpackages}[$j] =~ /\.rpm\s*$/ ))) { next; } push(@newcontent, ${$allpackages}[$j]); } } else { push(@newcontent, ${$content}[$i]); } } return (\@newcontent, $subdir); } ###################################################### # Including the system integration files into the # installation sets. ###################################################### sub put_systemintegration_into_installset { my ($newdir, $includepatharrayref, $allvariables, $modulesarrayref) = @_; my $destdir = $newdir; # adding System integration files my $sourcefile = ""; # Finding the modules defined in scp (with flag SYSTEMMODULE) # Getting name of package from scp-Module # Search package in list off all include files # Copy file into installation set and unpack it (always tar.gz) # Create xpd file and put it into xpd directory # tar.gz can contain a different number of packages -> automatically create hidden sub modules # xpd file has to be created completely from module and package itself (-> no packagelist!) # Collect all modules with flag "SYSTEMMODULE" my $allmodules = collect_modules_with_style("SYSTEMMODULE", $modulesarrayref); $allmodules = remove_modules_without_package($allmodules); for ( my $i = 0; $i <= $#{$allmodules}; $i++ ) { my $onemodule = ${$allmodules}[$i]; my $packagetarfilename = $onemodule->{'PackageName'}; my $infoline = "Including into installation set: $packagetarfilename\n"; push( @installer::globals::logfileinfo, $infoline); my $sourcepathref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$packagetarfilename, $includepatharrayref, 1); if ( $$sourcepathref eq "" ) { installer::exiter::exit_program("ERROR: Source path not found for $packagetarfilename!", "copy_systemintegration_files"); } # Collecting all packages in directory "packages" or "RPMS" my $oldcontent = installer::systemactions::read_directory($destdir); copy_and_unpack_tar_gz_files($$sourcepathref, $destdir); # Finding new content -> that is the package name my ($newcontent, $allcontent ) = installer::systemactions::find_new_content_in_directory($destdir, $oldcontent); # special handling, if new content is a directory my $subdir = ""; if ( ! $installer::globals::issolarispkgbuild ) { ($newcontent, $subdir) = control_subdirectories($newcontent); } if (( $installer::globals::isxpdplatform ) && ( $allvariables->{'XPDINSTALLER'} )) { installer::xpdinstaller::create_xpd_file_for_systemintegration($onemodule, $newcontent, $modulesarrayref, $subdir); } } } ###################################################### # Analyzing the Unix installation path. # From the installation path /opt/openofficeorg20 # is the part /opt relocatable and the part # openofficeorg20 static. ###################################################### sub analyze_rootpath { my ($rootpath, $staticpathref, $relocatablepathref, $allvariables) = @_; $rootpath =~ s/\/\s*$//; # removing ending slash ############################################################## # Version 1: "/opt" is variable and "openofficeorg20" fixed ############################################################## # my $staticpath = $rootpath; # installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$staticpath); # $$staticpathref = $staticpath; # will be "openofficeorg20" # my $relocatablepath = $rootpath; # installer::pathanalyzer::get_path_from_fullqualifiedname(\$relocatablepath); # $$relocatablepathref = $relocatablepath; # will be "/opt/" ############################################################## # Version 2: "/opt/openofficeorg20" is variable and "" fixed ############################################################## # if ( $$relocatablepathref eq "" ) # relocatablepath is not defined in package list # { # $$staticpathref = ""; # will be "" # $$relocatablepathref = $rootpath . "\/"; # relocatable path must end with "/", will be "/opt/openofficeorg20/" # # setting the static path to the hostname of the directory with style OFFICEDIRECTORY # if ( $allvariables->{'SETSTATICPATH'} ) { $$staticpathref = $installer::globals::officedirhostname; } # # } # else # relocatablepath is defined in package list # { # $$relocatablepathref =~ s/\/\s*$//; # removing ending slash # $$relocatablepathref = $$relocatablepathref . "\/"; # relocatable path must end with "/" # my $staticpath = $rootpath; # $staticpath =~ s/\Q$$relocatablepathref\E//; # $staticpath =~ s/\/\s*$//; # $$staticpathref = $staticpath; # } ############################################################## # Version 3: "/" is variable and "/opt/openofficeorg20" fixed ############################################################## $$relocatablepathref = "/"; # Static path has to contain the office directory name. This is replaced in shellscripts. $$staticpathref = $rootpath . $installer::globals::separator . $installer::globals::officedirhostname; # For RPM version 3.x it is required, that Prefix is not "/" in spec file. In this case --relocate will not work, # because RPM 3.x says, that the package is not relocatable. Therefore we have to use Prefix=/opt and for # all usages of --relocate this path has to be on both sides of the "=": --relocate /opt=/opt . if ( $installer::globals::islinuxrpmbuild ) { $$relocatablepathref = $rootpath . "\/"; # relocatable path must end with "/", will be "/opt/" $$staticpathref = $installer::globals::officedirhostname; # to be used as replacement in shell scripts } if ( $installer::globals::islinuxdebbuild ) { $$relocatablepathref = ""; # $$staticpathref is already "/opt/openoffice.org3", no additional $rootpath required. # $$staticpathref = $rootpath . $installer::globals::separator . $$staticpathref; # no relocatibility for Debian } } ###################################################### # Including license and readme into # Unix installation sets. ###################################################### sub put_installsetfiles_into_installset { my ($destdir) = @_; # All files for the installation set are saved in the global # array @installer::globals::installsetfiles for ( my $i = 0; $i <= $#installer::globals::installsetfiles; $i++ ) { my $onefile = $installer::globals::installsetfiles[$i]; my $sourcefile = $onefile->{'sourcepath'}; my $destfile = ""; if ( $installer::globals::addjavainstaller ) { $destfile = $onefile->{'Name'}; } else { $destfile = $destdir . $installer::globals::separator . $onefile->{'Name'}; } installer::systemactions::copy_one_file($sourcefile, $destfile); my $infoline = "Adding to installation set \"$destfile\" from source \"$sourcefile\".\n"; push( @installer::globals::logfileinfo, $infoline); } } ###################################################### # Replacing one variable in patchinfo file ###################################################### sub replace_one_variable_in_file { my ( $file, $placeholder, $value ) = @_; for ( my $i = 0; $i <= $#{$file}; $i++ ) { ${$file}[$i] =~ s/$placeholder/$value/g; } } ###################################################### # Setting variables in the patchinfo file ###################################################### sub set_patchinfo { my ( $patchinfofile, $patchid, $allvariables ) = @_; # Setting: PATCHIDPLACEHOLDER and ARCHITECTUREPLACEHOLDER and PATCHCORRECTSPLACEHOLDER replace_one_variable_in_file($patchinfofile, "PATCHIDPLACEHOLDER", $patchid); my $architecture = ""; if ( $installer::globals::issolarissparcbuild ) { $architecture = "sparc"; } if ( $installer::globals::issolarisx86build ) { $architecture = "i386"; } replace_one_variable_in_file($patchinfofile, "ARCHITECTUREPLACEHOLDER", $architecture); if ( ! $allvariables->{'SOLARISPATCHCORRECTS'} ) { installer::exiter::exit_program("ERROR: No setting for PATCH_CORRECTS in zip list file!", "set_patchinfo"); } my $patchcorrects = $allvariables->{'SOLARISPATCHCORRECTS'}; replace_one_variable_in_file($patchinfofile, "PATCHCORRECTSPLACEHOLDER", $patchcorrects); # Setting also PATCH_REQUIRES in patch info file, if entry in zip list file exists my $requiresstring = ""; if ( $installer::globals::issolarissparcbuild ) { $requiresstring = "SOLSPARCPATCHREQUIRES"; } if ( $installer::globals::issolarisx86build ) { $requiresstring = "SOLIAPATCHREQUIRES"; } if ( $allvariables->{$requiresstring} ) { my $newline = "PATCH_REQUIRES=\"" . $allvariables->{$requiresstring} . "\"" . "\n"; push(@{$patchinfofile}, $newline); } } ###################################################### # Finalizing patch: Renaming directory and # including additional patch files. ###################################################### sub finalize_patch { my ( $newepmdir, $allvariables ) = @_; my $patchidname = "SOLSPARCPATCHID"; if ( $installer::globals::issolarisx86build ) { $patchidname = "SOLIAPATCHID"; } if ( ! $allvariables->{$patchidname} ) { installer::exiter::exit_program("ERROR: Variable $patchidname not defined in zip list file!", "finalize_patch"); } my $patchid = $allvariables->{$patchidname}; installer::systemactions::rename_directory($newepmdir, $patchid); # Copying all typical patch files into the patch directory # All patch file names are stored in @installer::globals::solarispatchfiles # Location of the file is $installer::globals::patchincludepath my $sourcepath = $installer::globals::patchincludepath; $sourcepath =~ s/\/\s*$//; for ( my $i = 0; $i <= $#installer::globals::solarispatchfiles; $i++ ) { my $sourcefile = $sourcepath . $installer::globals::separator . $installer::globals::solarispatchfiles[$i]; my $destfile = $patchid . $installer::globals::separator . $installer::globals::solarispatchfiles[$i]; installer::systemactions::copy_one_file($sourcefile, $destfile); } # And editing the patchinfo file my $patchinfofilename = $patchid . $installer::globals::separator . "patchinfo"; my $patchinfofile = installer::files::read_file($patchinfofilename); set_patchinfo($patchinfofile, $patchid, $allvariables); installer::files::save_file($patchinfofilename, $patchinfofile); } ###################################################### # Finalizing Linux patch: Renaming directory and # including additional patch files. ###################################################### sub finalize_linux_patch { my ( $newepmdir, $allvariables, $includepatharrayref ) = @_; # Copying the setup into the patch directory # and including the list of RPMs into it print "... creating patch setup ...\n"; installer::logger::include_header_into_logfile("Creating Linux patch setup:"); # find and read setup script template my $scriptfilename = "linuxpatchscript.sh"; my $scriptref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$scriptfilename, $includepatharrayref, 0); if ($$scriptref eq "") { installer::exiter::exit_program("ERROR: Could not find patch script template $scriptfilename!", "finalize_linux_patch"); } my $scriptfile = installer::files::read_file($$scriptref); my $infoline = "Found script file $scriptfilename: $$scriptref \n"; push( @installer::globals::logfileinfo, $infoline); # # Collecting all RPMs in the patch directory # # my $fileextension = "rpm"; # my $rpmfiles = installer::systemactions::find_file_with_file_extension($fileextension, $newepmdir); # if ( ! ( $#{$rpmfiles} > -1 )) { installer::exiter::exit_program("ERROR: Could not find rpm in directory $newepmdir!", "finalize_linux_patch"); } # for ( my $i = 0; $i <= $#{$rpmfiles}; $i++ ) { installer::pathanalyzer::make_absolute_filename_to_relative_filename(\${$rpmfiles}[$i]); } # # my $installline = ""; # # for ( my $i = 0; $i <= $#{$rpmfiles}; $i++ ) # { # $installline = $installline . " rpm --prefix \$PRODUCTINSTALLLOCATION -U $newepmdir/${$rpmfiles}[$i]\n"; # } # # $installline =~ s/\s*$//; # # for ( my $j = 0; $j <= $#{$scriptfile}; $j++ ) # { # ${$scriptfile}[$j] =~ s/INSTALLLINES/$installline/; # } # Replacing the productname my $productname = $allvariables->{'PRODUCTNAME'}; $productname = lc($productname); $productname =~ s/ /_/g; # abc office -> abc_office # $productname =~ s/\.//g; # openoffice.org -> openofficeorg $infoline = "Adding productname $productname into Linux patch script\n"; push( @installer::globals::logfileinfo, $infoline); for ( my $j = 0; $j <= $#{$scriptfile}; $j++ ) { ${$scriptfile}[$j] =~ s/PRODUCTNAMEPLACEHOLDER/$productname/; } # Saving the file my $newscriptfilename = "setup"; # $newepmdir . $installer::globals::separator . "setup"; installer::files::save_file($newscriptfilename, $scriptfile); $infoline = "Saved Linux patch setup $newscriptfilename \n"; push( @installer::globals::logfileinfo, $infoline); # Setting unix rights 755 my $localcall = "chmod 775 $newscriptfilename \>\/dev\/null 2\>\&1"; system($localcall); } 1;