diff options
author | Jens-Heiner Rechtien <hr@openoffice.org> | 2009-05-18 15:53:14 +0000 |
---|---|---|
committer | Jens-Heiner Rechtien <hr@openoffice.org> | 2009-05-18 15:53:14 +0000 |
commit | 2ceb0d94f73d37949edf8686cd55a56c2cab68f0 (patch) | |
tree | fac4d2bb9f784d59b2740bdf707bd9b158d0c4a5 | |
parent | 11f657573b76832bcee904dbf0c133a616f85886 (diff) |
CWS-TOOLING: integrate CWS native240
2009-05-07 14:15:40 +0200 is r271664 : #i100983# signing process also cygwin ready
2009-05-07 11:54:19 +0200 is r271650 : #i100983# signing process also cygwin ready
2009-05-06 17:37:11 +0200 is r271606 : #i100983# signing process also cygwin ready
2009-05-05 18:28:49 +0200 is r271549 : #i100983# signing process also cygwin ready
2009-04-09 15:51:50 +0200 is r270712 : #i100983# cygwin improvements
2009-04-09 13:57:01 +0200 is r270706 : #i100983# improve cygwin support
2009-04-09 13:56:09 +0200 is r270705 : #i100983# improve cygwin support
2009-04-09 13:55:11 +0200 is r270704 : #i100983# improve cygwin support
2009-04-09 13:54:46 +0200 is r270703 : #i100983# improve cygwin support
2009-04-09 13:54:19 +0200 is r270702 : #i100983# improve cygwin support
2009-04-09 13:53:55 +0200 is r270701 : #i100983# improve cygwin support
2009-04-09 13:53:24 +0200 is r270700 : #i100983# improve cygwin support
2009-04-09 13:52:44 +0200 is r270699 : #i100983# improve cygwin support
2009-04-09 13:51:59 +0200 is r270698 : #i100983# improve cygwin support
2009-04-09 13:51:31 +0200 is r270697 : #i100983# improve cygwin support
2009-04-09 13:48:29 +0200 is r270696 : #i100983# improve cygwin support
2009-04-09 13:47:19 +0200 is r270695 : #i100983# improve cygwin support
2009-04-09 13:47:04 +0200 is r270694 : #i100983# improve cygwin support
2009-04-09 13:45:55 +0200 is r270693 : #i100983# improve cygwin support
2009-04-09 13:45:40 +0200 is r270692 : #i100983# improve cygwin support
2009-04-09 13:44:57 +0200 is r270691 : #i100983# improve cygwin support
2009-04-09 13:44:09 +0200 is r270690 : #i100983# improve cygwin support
19 files changed, 1500 insertions, 286 deletions
diff --git a/solenv/bin/make_download.pl b/solenv/bin/make_download.pl index d39d42f2c..96a152a83 100644 --- a/solenv/bin/make_download.pl +++ b/solenv/bin/make_download.pl @@ -52,6 +52,7 @@ use installer::windows::sign; installer::downloadsigner::getparameter(); installer::downloadsigner::checkparameter(); +my $temppath = installer::downloadsigner::set_temp_path(); my $infofilelist = installer::downloadsigner::createproductlist(); installer::downloadsigner::publishproductlist($infofilelist); @@ -62,19 +63,21 @@ foreach my $infofilename ( @{$infofilelist} ) my $success = 1; my $do_copy = 1; my $followmeinfohash = installer::followme::read_followme_info($infofilename); - installer::downloadsigner::setlogfilename(); + installer::downloadsigner::setlogfilename(); # Successful after reading followme file, resetting log file + if ( $installer::globals::writetotemp ) { installer::downloadsigner::set_output_pathes_to_temp($followmeinfohash, $temppath); } + if ( $installer::globals::useminor ) { installer::downloadsigner::set_minor_into_pathes($followmeinfohash, $temppath); } if (( ! $installer::globals::iswindowsbuild ) && ( $installer::globals::dosign )) { installer::logger::print_message( "... WARNING: Signing only for Windows platforms active ...\n" ); } - installer::logger::include_header_into_logfile("Reading include pathes"); - installer::worker::collect_all_files_from_includepathes($followmeinfohash->{'includepatharray'}); + # installer::logger::include_header_into_logfile("Reading include pathes"); + # installer::worker::collect_all_files_from_includepathes($followmeinfohash->{'includepatharray'}); if (( $installer::globals::iswindowsbuild ) && ( $installer::globals::dosign )) { - $followmeinfohash->{'finalinstalldir'} = installer::windows::sign::sign_install_set($followmeinfohash, $do_copy); + $followmeinfohash->{'finalinstalldir'} = installer::windows::sign::sign_install_set($followmeinfohash, $do_copy, $temppath); ($success, $followmeinfohash->{'finalinstalldir'}) = installer::worker::analyze_and_save_logfile($followmeinfohash->{'loggingdir'}, $followmeinfohash->{'finalinstalldir'}, @@ -86,37 +89,45 @@ foreach my $infofilename ( @{$infofilelist} ) if ( ! $success ) { installer::exiter::exit_program("ERROR: Signing installation set failed: $followmeinfohash->{'finalinstalldir'}", "Main"); } } - $followmeinfohash->{'finalinstalldir'} = installer::download::create_download_sets($followmeinfohash->{'finalinstalldir'}, - $followmeinfohash->{'includepatharray'}, - $followmeinfohash->{'allvariableshash'}, - $followmeinfohash->{'downloadname'}, - \$followmeinfohash->{'languagestring'}, - $followmeinfohash->{'languagesarray'}); - - ($success, $followmeinfohash->{'finalinstalldir'}) = installer::worker::analyze_and_save_logfile($followmeinfohash->{'loggingdir'}, - $followmeinfohash->{'finalinstalldir'}, - $followmeinfohash->{'installlogdir'}, - "", - \$followmeinfohash->{'languagestring'}, - $followmeinfohash->{'currentinstallnumber'}); - - if (( $success ) && ( $installer::globals::iswindowsbuild ) && ( $installer::globals::dosign )) + if ( ! $installer::globals::nodownload ) { - $do_copy = 0; - $followmeinfohash->{'finalinstalldir'} = installer::windows::sign::sign_install_set($followmeinfohash, $do_copy); - - $followmeinfohash->{'finalinstalldir'} = installer::worker::analyze_and_save_logfile($followmeinfohash->{'loggingdir'}, - $followmeinfohash->{'finalinstalldir'}, - $followmeinfohash->{'installlogdir'}, - "", - \$followmeinfohash->{'languagestring'}, - $followmeinfohash->{'currentinstallnumber'}); + $followmeinfohash->{'finalinstalldir'} = installer::download::create_download_sets($followmeinfohash->{'finalinstalldir'}, + $followmeinfohash->{'includepatharray'}, + $followmeinfohash->{'allvariableshash'}, + $followmeinfohash->{'downloadname'}, + \$followmeinfohash->{'languagestring'}, + $followmeinfohash->{'languagesarray'}); + + ($success, $followmeinfohash->{'finalinstalldir'}) = installer::worker::analyze_and_save_logfile($followmeinfohash->{'loggingdir'}, + $followmeinfohash->{'finalinstalldir'}, + $followmeinfohash->{'installlogdir'}, + "", + \$followmeinfohash->{'languagestring'}, + $followmeinfohash->{'currentinstallnumber'}); + + if (( $success ) && ( $installer::globals::iswindowsbuild ) && ( $installer::globals::dosign )) + { + $do_copy = 0; + $followmeinfohash->{'finalinstalldir'} = installer::windows::sign::sign_install_set($followmeinfohash, $do_copy, $temppath); + + ($success, $followmeinfohash->{'finalinstalldir'}) = installer::worker::analyze_and_save_logfile($followmeinfohash->{'loggingdir'}, + $followmeinfohash->{'finalinstalldir'}, + $followmeinfohash->{'installlogdir'}, + "", + \$followmeinfohash->{'languagestring'}, + $followmeinfohash->{'currentinstallnumber'}); + } + } + + if ( $success ) + { + installer::worker::clean_output_tree(); + if ( $installer::globals::followme_from_directory ) { installer::downloadsigner::rename_followme_infofile($infofilename); } } installer::logger::stoptime(); } - #################################### # Main program end #################################### diff --git a/solenv/bin/make_installer.pl b/solenv/bin/make_installer.pl index 2f876010e..445a44b46 100644 --- a/solenv/bin/make_installer.pl +++ b/solenv/bin/make_installer.pl @@ -2298,7 +2298,7 @@ for ( my $n = 0; $n <= $#installer::globals::languageproducts; $n++ ) # Creating Windows msp patches ####################################################### - if (( $is_success ) && ( $installer::globals::updatedatabase ) && ( $allvariableshashref->{'CREATE_MSP_INSTALLSET'} ) && ( ! ( $^O =~ /cygwin/i ))) # not supported for cygwin yet + if (( $is_success ) && ( $installer::globals::updatedatabase ) && ( $allvariableshashref->{'CREATE_MSP_INSTALLSET'} )) { # Required: # Temp path for administrative installations: $installer::globals::temppath diff --git a/solenv/bin/modules/installer/archivefiles.pm b/solenv/bin/modules/installer/archivefiles.pm index fb8ff9f81..26d0b8af1 100644 --- a/solenv/bin/modules/installer/archivefiles.pm +++ b/solenv/bin/modules/installer/archivefiles.pm @@ -31,6 +31,7 @@ package installer::archivefiles; +use Archive::Zip qw( :ERROR_CODES :CONSTANTS ); use installer::converter; use installer::existence; use installer::exiter; @@ -198,15 +199,22 @@ sub resolving_archive_flag if ( $installer::globals::dounzip ) { installer::systemactions::create_directory($unzipdir); } # creating subdirectories with the names of the zipfiles - $systemcall = "$installer::globals::unzippath -l $sourcepath |"; - open (UNZIP, "$systemcall"); - my @zipfile = <UNZIP>; - close (UNZIP); + my $zip = Archive::Zip->new(); + if ( $zip->read($sourcepath) != AZ_OK ) + { + $infoline = "ERROR: Could not unzip $sourcepath\n"; + push( @installer::globals::logfileinfo, $infoline); + } - $infoline = "Systemcall: $systemcall\n"; - push( @installer::globals::logfileinfo, $infoline); + my $counter = 0; + my $contains_dll = 0; + foreach my $member ( $zip->memberNames() ) + { + $counter++; + if ( $member =~ /.dll\s*$/ ) { $contains_dll = 1; } + } - if (!( $#zipfile > -1 )) # the zipfile is empty + if (! ( $counter > 0 )) # the zipfile is empty { $infoline = "ERROR: Could not unzip $sourcepath\n"; push( @installer::globals::logfileinfo, $infoline); @@ -214,22 +222,11 @@ sub resolving_archive_flag } else { - # now really unpacking the files - # Parameter -o : overwrite files without prompting - # Parameter -q : quiet mode - if ( $installer::globals::dounzip ) # really unpacking the files { - $returnvalue = 1; - $systemcall = "$installer::globals::unzippath -o -q $sourcepath -d $unzipdir"; - $returnvalue = system($systemcall); + if ( $zip->extractTree("", $unzipdir) != AZ_OK ) { installer::exiter::exit_program("ERROR: $infoline", "resolving_archive_flag"); } - $infoline = "Systemcall: $systemcall\n"; - push( @installer::globals::logfileinfo, $infoline); - - if ($returnvalue) { installer::exiter::exit_program("ERROR: $infoline", "resolving_archive_flag"); } - - if ( $^O =~ /cygwin/i ) + if (( $^O =~ /cygwin/i ) && ( $contains_dll )) { # Make dll's executable $systemcall = "cd $unzipdir; find . -name \\*.dll -exec chmod 775 \{\} \\\;"; @@ -264,134 +261,120 @@ sub resolving_archive_flag my $zipfileref = \@zipfile; my $unziperror = 0; - # Format: Length, Date, Time, Name - # This includes new destination directories! - - for ( my $j = 0; $j <= $#{$zipfileref}; $j++ ) + foreach my $zipname ( $zip->memberNames() ) { - my $line = ${$zipfileref}[$j]; - - # Format: - # 0 07-25-03 18:21 dir1/ - # 1241 07-25-03 18:21 dir1/so7drawing.desktop - - if ( $line =~ /^\s*(\d+)\s+(\S+)\s+(\S+)\s+(\S+.*\S+?)\s*$/ ) - { - my $zipsize = $1; - my $zipdate = $2; - my $ziptime = $3; - my $zipname = $4; + # Format from Archive:::Zip : + # dir1/ + # dir1/so7drawing.desktop - # some directories and files (from the help) start with "./simpress.idx" + # some directories and files (from the help) start with "./simpress.idx" - $zipname =~ s/^\s*\.\///; + $zipname =~ s/^\s*\.\///; - if ($installer::globals::iswin and $^O =~ /MSWin/i) { $zipname =~ s/\//\\/g; } + if ($installer::globals::iswin and $^O =~ /MSWin/i) { $zipname =~ s/\//\\/g; } - # if ( $zipsize == 0 ) # also files can have a size of 0 - if ( $zipname =~ /\Q$installer::globals::separator\E\s*$/ ) # slash or backslash at the end characterizes a directory - { - $zipname = $zipname . "\n"; - push(@{$additionalpathsref}, $zipname); + if ( $zipname =~ /\Q$installer::globals::separator\E\s*$/ ) # slash or backslash at the end characterizes a directory + { + $zipname = $zipname . "\n"; + push(@{$additionalpathsref}, $zipname); - # Also needed here: - # Name - # Language - # ismultilingual - # Basedirectory + # Also needed here: + # Name + # Language + # ismultilingual + # Basedirectory - # This is not needed, because the list of all directories for the - # epm list file is generated from the destination directories of the - # files included in the product! + # This is not needed, because the list of all directories for the + # epm list file is generated from the destination directories of the + # files included in the product! + } + else + { + my %newfile = (); + %newfile = %{$onefile}; + $newfile{'Name'} = $zipname; + my $destination = $onefile->{'destination'}; + installer::pathanalyzer::get_path_from_fullqualifiedname(\$destination); + $newfile{'destination'} = $destination . $zipname; + $newfile{'sourcepath'} = $unzipdir . $zipname; + $newfile{'zipfilename'} = $onefile->{'Name'}; + $newfile{'zipfilesource'} = $onefile->{'sourcepath'}; + $newfile{'zipfiledestination'} = $onefile->{'destination'}; + + if (( $use_internal_rights ) && ( ! $installer::globals::iswin )) + { + my $value = sprintf("%o", (stat($newfile{'sourcepath'}))[2]); + $newfile{'UnixRights'} = substr($value, 3); + $infoline = "Setting unix rights for \"$newfile{'sourcepath'}\" to \"$newfile{'UnixRights'}\"\n"; + push( @installer::globals::logfileinfo, $infoline); } - else + + if ( $select_files ) { - my %newfile = (); - %newfile = %{$onefile}; - $newfile{'Name'} = $zipname; - my $destination = $onefile->{'destination'}; - installer::pathanalyzer::get_path_from_fullqualifiedname(\$destination); - $newfile{'destination'} = $destination . $zipname; - $newfile{'sourcepath'} = $unzipdir . $zipname; - $newfile{'zipfilename'} = $onefile->{'Name'}; - $newfile{'zipfilesource'} = $onefile->{'sourcepath'}; - $newfile{'zipfiledestination'} = $onefile->{'destination'}; - - if (( $use_internal_rights ) && ( ! $installer::globals::iswin )) + if ( ! installer::existence::exists_in_array($zipname,$selectlistfiles) ) { - my $value = sprintf("%o", (stat($newfile{'sourcepath'}))[2]); - $newfile{'UnixRights'} = substr($value, 3); - $infoline = "Setting unix rights for \"$newfile{'sourcepath'}\" to \"$newfile{'UnixRights'}\"\n"; + $infoline = "Removing from ARCHIVE file $onefilename: $zipname\n"; push( @installer::globals::logfileinfo, $infoline); + next; # ignoring files, that are not included in $selectlistfiles } + else + { + $infoline = "Keeping from ARCHIVE file $onefilename: $zipname\n"; + push( @installer::globals::logfileinfo, $infoline); + push( @keptfiles, $zipname); # collecting all kept files + } + } + + if ( $select_patch_files ) + { + # Is this file listed in the Patchfile list? + # $zipname (filename including path in zip file has to be listed in patchfile list - if ( $select_files ) + if ( ! installer::existence::exists_in_array($zipname,$patchlistfiles) ) { - if ( ! installer::existence::exists_in_array($zipname,$selectlistfiles) ) - { - $infoline = "Removing from ARCHIVE file $onefilename: $zipname\n"; - push( @installer::globals::logfileinfo, $infoline); - next; # ignoring files, that are not included in $selectlistfiles - } - else - { - $infoline = "Keeping from ARCHIVE file $onefilename: $zipname\n"; - push( @installer::globals::logfileinfo, $infoline); - push( @keptfiles, $zipname); # collecting all kept files - } + $newfile{'Styles'} =~ s/\bPATCH\b//; # removing the flag PATCH + $newfile{'Styles'} =~ s/\,\s*\,/\,/; + $newfile{'Styles'} =~ s/\(\s*\,/\(/; + $newfile{'Styles'} =~ s/\,\s*\)/\)/; + # $infoline = "Removing PATCH flag from: $zipname\n"; + # push( @installer::globals::logfileinfo, $infoline); } - - if ( $select_patch_files ) + else { - # Is this file listed in the Patchfile list? - # $zipname (filename including path in zip file has to be listed in patchfile list - - if ( ! installer::existence::exists_in_array($zipname,$patchlistfiles) ) - { - $newfile{'Styles'} =~ s/\bPATCH\b//; # removing the flag PATCH - $newfile{'Styles'} =~ s/\,\s*\,/\,/; - $newfile{'Styles'} =~ s/\(\s*\,/\(/; - $newfile{'Styles'} =~ s/\,\s*\)/\)/; - # $infoline = "Removing PATCH flag from: $zipname\n"; - # push( @installer::globals::logfileinfo, $infoline); - } - else - { - # $infoline = "Keeping PATCH flag at: $zipname\n"; - # push( @installer::globals::logfileinfo, $infoline); - push( @keptpatchflags, $zipname); # collecting all PATCH flags - } + # $infoline = "Keeping PATCH flag at: $zipname\n"; + # push( @installer::globals::logfileinfo, $infoline); + push( @keptpatchflags, $zipname); # collecting all PATCH flags } + } - if ( $rename_to_language ) - { - my $newzipname = put_language_into_name($zipname, $onelanguage); - my $oldfilename = $unzipdir . $zipname; - my $newfilename = $unzipdir . $newzipname; + if ( $rename_to_language ) + { + my $newzipname = put_language_into_name($zipname, $onelanguage); + my $oldfilename = $unzipdir . $zipname; + my $newfilename = $unzipdir . $newzipname; - installer::systemactions::copy_one_file($oldfilename, $newfilename); + installer::systemactions::copy_one_file($oldfilename, $newfilename); - $newfile{'Name'} = $newzipname; - $newfile{'destination'} = $destination . $newzipname; - $newfile{'sourcepath'} = $unzipdir . $newzipname; + $newfile{'Name'} = $newzipname; + $newfile{'destination'} = $destination . $newzipname; + $newfile{'sourcepath'} = $unzipdir . $newzipname; - $infoline = "RENAME_TO_LANGUAGE: Using $newzipname instead of $zipname!\n"; - push( @installer::globals::logfileinfo, $infoline); - } + $infoline = "RENAME_TO_LANGUAGE: Using $newzipname instead of $zipname!\n"; + push( @installer::globals::logfileinfo, $infoline); + } - my $sourcefiletest = $unzipdir . $zipname; - if ( ! -f $sourcefiletest ) - { - $infoline = "ATTENTION: Unzip failed for $sourcefiletest!\n"; - push( @installer::globals::logfileinfo, $infoline); - $unziperror = 1; - } + my $sourcefiletest = $unzipdir . $zipname; + if ( ! -f $sourcefiletest ) + { + $infoline = "ATTENTION: Unzip failed for $sourcefiletest!\n"; + push( @installer::globals::logfileinfo, $infoline); + $unziperror = 1; + } - # only adding the new line into the files array, if not in repeat modus + # only adding the new line into the files array, if not in repeat modus - if ( ! $repeat_unzip ) { push(@newallfilesarray, \%newfile); } - } - } + if ( ! $repeat_unzip ) { push(@newallfilesarray, \%newfile); } + } } # Comparing the content of @keptfiles and $selectlistfiles diff --git a/solenv/bin/modules/installer/control.pm b/solenv/bin/modules/installer/control.pm index f51550adf..aaf7c84cb 100644 --- a/solenv/bin/modules/installer/control.pm +++ b/solenv/bin/modules/installer/control.pm @@ -80,7 +80,7 @@ sub check_needed_files_in_path sub check_system_path { # The following files have to be found in the environment variable PATH - # All platforms: zip, unzip + # All platforms: zip # Windows only: msvcp70.dll, msvcr70.dll for regcomp.exe # Windows only: "msiinfo.exe", "msidb.exe", "uuidgen.exe", "makecab.exe", "msitran.exe", "expand.exe" for msi database and packaging @@ -103,7 +103,7 @@ sub check_system_path if (($installer::globals::iswin) && ($installer::globals::iswindowsbuild)) { - @needed_files_in_path = ("zip.exe", "unzip.exe", "msiinfo.exe", "msidb.exe", "uuidgen.exe", "makecab.exe", "msitran.exe", "expand.exe"); + @needed_files_in_path = ("zip.exe", "msiinfo.exe", "msidb.exe", "uuidgen.exe", "makecab.exe", "msitran.exe", "expand.exe"); if ( $installer::globals::compiler eq "wntmsci8" ) { @@ -120,11 +120,11 @@ sub check_system_path } elsif ($installer::globals::iswin) { - @needed_files_in_path = ("zip.exe", "unzip.exe"); + @needed_files_in_path = ("zip.exe"); } else { - @needed_files_in_path = ("zip", "unzip"); + @needed_files_in_path = ("zip"); } foreach $onefile ( @needed_files_in_path ) diff --git a/solenv/bin/modules/installer/download.pm b/solenv/bin/modules/installer/download.pm index 01479988d..36b9a0f8f 100644 --- a/solenv/bin/modules/installer/download.pm +++ b/solenv/bin/modules/installer/download.pm @@ -270,7 +270,18 @@ sub get_path_for_library my ($includepatharrayref) = @_; my $getuidlibraryname = "getuid.so"; - my $getuidlibraryref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$getuidlibraryname, $includepatharrayref, 0); + + my $getuidlibraryref = ""; + + if ( $installer::globals::include_pathes_read ) + { + $getuidlibraryref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$getuidlibraryname, $includepatharrayref, 0); + } + else + { + $getuidlibraryref = installer::scriptitems::get_sourcepath_from_filename_and_includepath_classic(\$getuidlibraryname, $includepatharrayref, 0); + } + if ($$getuidlibraryref eq "") { installer::exiter::exit_program("ERROR: Could not find $getuidlibraryname!", "get_path_for_library"); } return $$getuidlibraryref; @@ -777,12 +788,21 @@ sub put_banner_bmp_into_template if ( ! $allvariables->{'DOWNLOADBANNER'} ) { installer::exiter::exit_program("ERROR: DOWNLOADBANNER not defined in product definition!", "put_banner_bmp_into_template"); } my $filename = $allvariables->{'DOWNLOADBANNER'}; - my $completefilenameref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$filename, $includepatharrayref, 0); + my $completefilenameref = ""; - if ( $^O =~ /cygwin/i ) { $$completefilenameref =~ s/\//\\/g; } + if ( $installer::globals::include_pathes_read ) + { + $completefilenameref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$filename, $includepatharrayref, 0); + } + else + { + $completefilenameref = installer::scriptitems::get_sourcepath_from_filename_and_includepath_classic(\$filename, $includepatharrayref, 0); + } if ($$completefilenameref eq "") { installer::exiter::exit_program("ERROR: Could not find download file $filename!", "put_banner_bmp_into_template"); } + if ( $^O =~ /cygwin/i ) { $$completefilenameref =~ s/\//\\/g; } + replace_one_variable($templatefile, "BANNERBMPPLACEHOLDER", $$completefilenameref); } @@ -798,12 +818,21 @@ sub put_welcome_bmp_into_template if ( ! $allvariables->{'DOWNLOADBITMAP'} ) { installer::exiter::exit_program("ERROR: DOWNLOADBITMAP not defined in product definition!", "put_welcome_bmp_into_template"); } my $filename = $allvariables->{'DOWNLOADBITMAP'}; - my $completefilenameref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$filename, $includepatharrayref, 0); + my $completefilenameref = ""; - if ( $^O =~ /cygwin/i ) { $$completefilenameref =~ s/\//\\/g; } + if ( $installer::globals::include_pathes_read ) + { + $completefilenameref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$filename, $includepatharrayref, 0); + } + else + { + $completefilenameref = installer::scriptitems::get_sourcepath_from_filename_and_includepath_classic(\$filename, $includepatharrayref, 0); + } if ($$completefilenameref eq "") { installer::exiter::exit_program("ERROR: Could not find download file $filename!", "put_welcome_bmp_into_template"); } + if ( $^O =~ /cygwin/i ) { $$completefilenameref =~ s/\//\\/g; } + replace_one_variable($templatefile, "WELCOMEBMPPLACEHOLDER", $$completefilenameref); } @@ -819,12 +848,21 @@ sub put_setup_ico_into_template if ( ! $allvariables->{'DOWNLOADSETUPICO'} ) { installer::exiter::exit_program("ERROR: DOWNLOADSETUPICO not defined in product definition!", "put_setup_ico_into_template"); } my $filename = $allvariables->{'DOWNLOADSETUPICO'}; - my $completefilenameref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$filename, $includepatharrayref, 0); + my $completefilenameref = ""; - if ( $^O =~ /cygwin/i ) { $$completefilenameref =~ s/\//\\/g; } + if ( $installer::globals::include_pathes_read ) + { + $completefilenameref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$filename, $includepatharrayref, 0); + } + else + { + $completefilenameref = installer::scriptitems::get_sourcepath_from_filename_and_includepath_classic(\$filename, $includepatharrayref, 0); + } if ($$completefilenameref eq "") { installer::exiter::exit_program("ERROR: Could not find download file $filename!", "put_setup_ico_into_template"); } + if ( $^O =~ /cygwin/i ) { $$completefilenameref =~ s/\//\\/g; } + replace_one_variable($templatefile, "SETUPICOPLACEHOLDER", $$completefilenameref); } @@ -957,6 +995,7 @@ sub get_file_list my $onefile = ${$files}[$j]; my $fileline = " " . "File" . " " . "\"" . $onefile . "\"" . "\n"; + if ( $^O =~ /cygwin/i ) { $fileline =~ s/\//\\/g; } @@ -1533,6 +1572,8 @@ sub call_nsis installer::logger::print_message( "... starting $makensisexe ... \n" ); + if( $^O =~ /cygwin/i ) { $nsifile =~ s/\\/\//g; } + my $systemcall = "$makensisexe $nsifile |"; my $infoline = "Systemcall: $systemcall\n"; @@ -1706,6 +1747,7 @@ sub create_download_sets # removing existing directory "_native_packed_inprogress" and "_native_packed_witherror" and "_native_packed" my $downloaddir = $firstdir . $lastdir; + if ( -d $downloaddir ) { installer::systemactions::remove_complete_directory($downloaddir); } my $olddir = $downloaddir; @@ -1742,7 +1784,18 @@ sub create_download_sets { # find and read setup script template my $scriptfilename = "downloadscript.sh"; - my $scriptref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$scriptfilename, $includepatharrayref, 0); + + my $scriptref = ""; + + if ( $installer::globals::include_pathes_read ) + { + $scriptref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$scriptfilename, $includepatharrayref, 0); + } + else + { + $scriptref = installer::scriptitems::get_sourcepath_from_filename_and_includepath_classic(\$scriptfilename, $includepatharrayref, 0); + } + if ($$scriptref eq "") { installer::exiter::exit_program("ERROR: Could not find script file $scriptfilename!", "create_download_sets"); } my $scriptfile = installer::files::read_file($$scriptref); @@ -1797,7 +1850,18 @@ sub create_download_sets # find and read the nsi file template my $templatefilename = "downloadtemplate.nsi"; - my $templateref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$templatefilename, $includepatharrayref, 0); + + my $templateref = ""; + + if ( $installer::globals::include_pathes_read ) + { + $templateref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$templatefilename, $includepatharrayref, 0); + } + else + { + $templateref = installer::scriptitems::get_sourcepath_from_filename_and_includepath_classic(\$templatefilename, $includepatharrayref, 0); + } + if ($$templateref eq "") { installer::exiter::exit_program("ERROR: Could not find nsi template file $templatefilename!", "create_download_sets"); } my $templatefile = installer::files::read_file($$templateref); diff --git a/solenv/bin/modules/installer/downloadsigner.pm b/solenv/bin/modules/installer/downloadsigner.pm index e19e7c84f..ba07973f7 100644 --- a/solenv/bin/modules/installer/downloadsigner.pm +++ b/solenv/bin/modules/installer/downloadsigner.pm @@ -45,12 +45,23 @@ sub usage { print <<Ende; -------------------------------------------------------------------------------- -make_download V1.0 (c) Ingo Schmidt-Rosbiegal 2009 +make_download V1.0 The following parameter are needed: -d: Full path to the file containing the follow-me info or to a directory containing the follow-me info files. In the latter case, all follow-me - info files are evaluated. + info files are evaluated. If a directory is used, the successfully used + follow-me info files are renamed using a string "success". Files with + this string are ignored in repeated processes using "-d" with a + directory. + The following parameter are optional: +-nodownload: Only signing, no creation of download sets (Windows only) +-useminor: Important for installation sets, created without minor set +-writetotemp: Necessary, if you do not want to write into solver + This can be caused by missing privileges (Windows only) +-internalcabinet: Not only the cabinet files are signed, but also all + files included in the cabinet files (Windows only). + -sign: Uses signing mechanism to sign installation sets If \"-sign\" is set, the following two parameter are required: -pfx: Full path to the pfx file @@ -60,17 +71,19 @@ Examples: Specifying an installation set (with "-d"): -perl make_sign_and_download.pl -d <followmeinfofilename> -perl make_sign_and_download.pl -d <followmeinfofilename> - -sign - -pfx <pfxfilename> - -pw <passwordfilename> +perl make_download.pl -d <followmeinfofilename> + +perl make_download.pl -d <followmeinfofilename> + -sign + -pfx <pfxfilename> + -pw <passwordfilename> or without specifying an installation set: -perl make_sign_and_download.pl -sign - -pfx <pfxfilename> - -pw <passwordfilename> +perl make_download.pl -d <followmedirectory> + -sign + -pfx <pfxfilename> + -pw <passwordfilename> -------------------------------------------------------------------------------- Ende exit(-1); @@ -92,6 +105,10 @@ sub getparameter elsif ($param eq "-pw") { $installer::globals::pwfile = shift(@ARGV); } elsif ($param eq "-pfx") { $installer::globals::pfxfile = shift(@ARGV); } elsif ($param eq "-sign") { $installer::globals::dosign = 1; } + elsif ($param eq "-nodownload") { $installer::globals::nodownload = 1; } + elsif ($param eq "-writetotemp") { $installer::globals::writetotemp = 1; } + elsif ($param eq "-useminor") { $installer::globals::useminor = 1; } + elsif ($param eq "-internalcabinet") { $installer::globals::internal_cabinet_signing = 1; } else { installer::logger::print_error( "unknown parameter: $param" ); @@ -150,6 +167,165 @@ sub checkparameter } ############################################# +# Setting the temporary path for the download +# and signing process +############################################# + +sub set_temp_path +{ + my $temppath = ""; + my $pid = $$; # process id + my $time = time(); # time + my $helperdir = "unpackdir_" . $pid . $time; + + if (( $ENV{'TMP'} ) || ( $ENV{'TEMP'} )) + { + if ( $ENV{'TMP'} ) { $temppath = $ENV{'TMP'}; } + elsif ( $ENV{'TEMP'} ) { $temppath = $ENV{'TEMP'}; } + $temppath =~ s/\Q$installer::globals::separator\E\s*$//; # removing ending slashes and backslashes + $temppath = $temppath . $installer::globals::separator . $helperdir; + + if( $^O =~ /cygwin/i ) + { + $temppath = qx{cygpath -w "$temppath"}; + $temppath =~ s/\\/\//g; + $temppath =~ s/\s*$//g; + } + + installer::systemactions::create_directory_structure($temppath); + } + else + { + installer::logger::print_error( "Error: TMP and TEMP not defined. This is required for this process.\n" ); + usage(); + exit(-1); + } + + installer::logger::print_message( "\n... using output path: $temppath ...\n" ); + + push(@installer::globals::removedirs, $temppath); + + return $temppath; +} + +############################################# +# Setting output pathes to temp directory +# This are the: +# unpackpath and the loggingdir +############################################# + +sub set_output_pathes_to_temp +{ + my ($followmeinfohash, $temppath) = @_; + + $followmeinfohash->{'loggingdir'} = $temppath . $installer::globals::separator; + $installer::globals::unpackpath = $temppath; +} + +############################################# +# Setting the minor into the pathes. This is +# required, if the original installation set +# was created without minor +# Value is always saved in +# $installer::globals::lastminor +# which is saved in the follow_me file +############################################# + +sub set_minor_into_pathes +{ + my ($followmeinfohash, $temppath) = @_; + + installer::logger::print_message( "\n... forcing into minor: $installer::globals::lastminor ...\n" ); + + my @pathnames = ("bin", "doc", "inc", "lib", "pck", "res", "xml"); + my $sourcename = "src"; + my $srcpath = $installer::globals::separator . $sourcename . $installer::globals::separator; + + if ( $installer::globals::minor ne "" ) + { + installer::logger::print_message( "\n... already defined minor: $installer::globals::minor -> ignoring parameter \"-useminor\" ...\n" ); + return; + } + + # Affected pathes: + # $contenthash{'installlogdir'} + # $contenthash{'includepatharray'} + # $installer::globals::unpackpath + # $installer::globals::idttemplatepath + # $installer::globals::idtlanguagepath + + installer::logger::include_header_into_logfile("Changing saved pathes to add the minor"); + my $infoline = "Old pathes:\n"; + push( @installer::globals::logfileinfo, $infoline); + $infoline = "\$followmeinfohash->{'installlogdir'}: $followmeinfohash->{'installlogdir'}\n"; + push( @installer::globals::logfileinfo, $infoline); + $infoline = "\$installer::globals::unpackpath: $installer::globals::unpackpath\n"; + push( @installer::globals::logfileinfo, $infoline); + $infoline = "\$installer::globals::idttemplatepath: $installer::globals::idttemplatepath\n"; + push( @installer::globals::logfileinfo, $infoline); + $infoline = "\$installer::globals::idtlanguagepath: $installer::globals::idtlanguagepath\n"; + push( @installer::globals::logfileinfo, $infoline); + $infoline = "Include pathes:\n"; + push( @installer::globals::logfileinfo, $infoline); + foreach my $path ( @{$followmeinfohash->{'includepatharray'}} ) { push( @installer::globals::logfileinfo, $path); } + + foreach $onepath ( @pathnames ) + { + my $oldvalue = $installer::globals::separator . $onepath . $installer::globals::separator; + my $newvalue = $installer::globals::separator . $onepath . "\." . $installer::globals::lastminor . $installer::globals::separator; + + if (( $followmeinfohash->{'installlogdir'} =~ /\Q$oldvalue\E/ ) && ( ! ( $followmeinfohash->{'installlogdir'} =~ /\Q$srcpath\E/ ))) { $followmeinfohash->{'installlogdir'} =~ s/\Q$oldvalue\E/$newvalue/; } + if (( $installer::globals::unpackpath =~ /\Q$oldvalue\E/ ) && ( ! ( $installer::globals::unpackpath =~ /\Q$srcpath\E/ ))) { $installer::globals::unpackpath =~ s/\Q$oldvalue\E/$newvalue/; } + if (( $installer::globals::idttemplatepath =~ /\Q$oldvalue\E/ ) && ( ! ( $installer::globals::idttemplatepath =~ /\Q$srcpath\E/ ))) { $installer::globals::idttemplatepath =~ s/\Q$oldvalue\E/$newvalue/; } + if (( $installer::globals::idtlanguagepath =~ /\Q$oldvalue\E/ ) && ( ! ( $installer::globals::idtlanguagepath =~ /\Q$srcpath\E/ ))) { $installer::globals::idtlanguagepath =~ s/\Q$oldvalue\E/$newvalue/; } + foreach my $path ( @{$followmeinfohash->{'includepatharray'}} ) { if (( $path =~ /\Q$oldvalue\E/ ) && ( ! ( $path =~ /\Q$srcpath\E/ ))) { $path =~ s/\Q$oldvalue\E/$newvalue/; } } + + # Checking for the end of the path + $oldvalue = $installer::globals::separator . $onepath; + $newvalue = $installer::globals::separator . $onepath . "\." . $installer::globals::lastminor; + + if (( $followmeinfohash->{'installlogdir'} =~ /\Q$oldvalue\E\s*$/ ) && ( ! ( $followmeinfohash->{'installlogdir'} =~ /\Q$srcpath\E/ ))) { $followmeinfohash->{'installlogdir'} =~ s/\Q$oldvalue\E\s*$/$newvalue/; } + if (( $installer::globals::unpackpath =~ /\Q$oldvalue\E\s*$/ ) && ( ! ( $installer::globals::unpackpath =~ /\Q$srcpath\E/ ))) { $installer::globals::unpackpath =~ s/\Q$oldvalue\E\s*$/$newvalue/; } + if (( $installer::globals::idttemplatepath =~ /\Q$oldvalue\E\s*$/ ) && ( ! ( $installer::globals::idttemplatepath =~ /\Q$srcpath\E/ ))) { $installer::globals::idttemplatepath =~ s/\Q$oldvalue\E\s*$/$newvalue/; } + if (( $installer::globals::idtlanguagepath =~ /\Q$oldvalue\E\s*$/ ) && ( ! ( $installer::globals::idtlanguagepath =~ /\Q$srcpath\E/ ))) { $installer::globals::idtlanguagepath =~ s/\Q$oldvalue\E\s*$/$newvalue/; } + foreach my $path ( @{$followmeinfohash->{'includepatharray'}} ) + { + if (( $path =~ /\Q$oldvalue\E\s*$/ ) && ( ! ( $path =~ /\Q$srcpath\E/ ))) + { + $path =~ s/\Q$oldvalue\E\s*$/$newvalue/; + $path = $path . "\n"; + } + } + } + + # And now can follow the replacement for the source path "src". Subdirs like "bin" in the source tree + # must not get the minor. This is instead "src.m9/instsetoo_native/common.pro/bin/..." + # Directory "src" can never be the end of the path + + my $newsrcpath = $installer::globals::separator . $sourcename . "\." . $installer::globals::lastminor . $installer::globals::separator; + + if ( $followmeinfohash->{'installlogdir'} =~ /\Q$srcpath\E/ ) { $followmeinfohash->{'installlogdir'} =~ s/\Q$srcpath\E/$newsrcpath/; } + if ( $installer::globals::unpackpath =~ /\Q$srcpath\E/ ) { $installer::globals::unpackpath =~ s/\Q$srcpath\E/$newsrcpath/; } + if ( $installer::globals::idttemplatepath =~ /\Q$srcpath\E/ ) { $installer::globals::idttemplatepath =~ s/\Q$srcpath\E/$newsrcpath/; } + if ( $installer::globals::idtlanguagepath =~ /\Q$srcpath\E/ ) { $installer::globals::idtlanguagepath =~ s/\Q$srcpath\E/$newsrcpath/; } + foreach my $path ( @{$followmeinfohash->{'includepatharray'}} ) { if ( $path =~ /\Q$srcpath\E/ ) { $path =~ s/\Q$srcpath\E/$newsrcpath/; } } + + $infoline = "\nNew pathes:\n"; + push( @installer::globals::logfileinfo, $infoline); + $infoline = "\$followmeinfohash->{'installlogdir'}: $followmeinfohash->{'installlogdir'}\n"; + push( @installer::globals::logfileinfo, $infoline); + $infoline = "\$installer::globals::unpackpath: $installer::globals::unpackpath\n"; + push( @installer::globals::logfileinfo, $infoline); + $infoline = "\$installer::globals::idttemplatepath: $installer::globals::idttemplatepath\n"; + push( @installer::globals::logfileinfo, $infoline); + $infoline = "\$installer::globals::idtlanguagepath: $installer::globals::idtlanguagepath\n"; + push( @installer::globals::logfileinfo, $infoline); + $infoline = "Include pathes:\n"; + push( @installer::globals::logfileinfo, $infoline); + foreach my $path ( @{$followmeinfohash->{'includepatharray'}} ) { push( @installer::globals::logfileinfo, $path); } +} + +############################################# # Setting the name of the log file ############################################# @@ -291,10 +467,13 @@ sub createproductlist # If "-d" specifies an installation set, there is only one product my @infofilelist = (); + my @infofilelist2 = (); if ( -f $installer::globals::followmeinfofilename ) { push(@infofilelist, $installer::globals::followmeinfofilename); + # Saving info, that this is a file + $installer::globals::followme_from_directory = 0; } elsif ( -d $installer::globals::followmeinfofilename ) { @@ -309,6 +488,9 @@ sub createproductlist exit(-1); } + # Saving info, that this is a directory + $installer::globals::followme_from_directory = 1; + # Collect all possible installation sets # CWS: All installation sets # Master: All installation sets with same major, minor and buildid. Additionally using the highest number. @@ -322,7 +504,7 @@ sub createproductlist { my $fullfilename = $installer::globals::followmeinfofilename . $installer::globals::separator . $onefile; my $installdir = get_property_from_file($fullfilename, "finalinstalldir"); - if (( $installdir ne "" ) && ( -d $installdir )) { push(@infofilelist, $fullfilename); } + if (( $installdir ne "" ) && ( -d $installdir )) { push(@infofilelist2, $fullfilename); } } } else @@ -334,10 +516,18 @@ sub createproductlist my $fullfilename = $installer::globals::followmeinfofilename . $installer::globals::separator . $onefile; # Check, if installation set still exists my $installdir = get_property_from_file($fullfilename, "finalinstalldir"); - if (( $installdir ne "" ) && ( -d $installdir )) { push(@infofilelist, $fullfilename); } + if (( $installdir ne "" ) && ( -d $installdir )) { push(@infofilelist2, $fullfilename); } } - } + } + # Removing all files, starting with "follow_me_success_" in their names. This have already been used successfully. + + foreach my $onefile ( @infofilelist2 ) + { + if ( $onefile =~ /follow_me_success_/ ) { next; } + push(@infofilelist, $onefile); + } + # Checking, if there is content in the list if ( ! ( $#infofilelist > -1 )) { @@ -374,4 +564,26 @@ sub logfollowmeinfohash foreach my $key ( sort keys %{$followmehash->{'allvariableshash'}} ) { print "allvariableshash: $key : $followmehash->{'allvariableshash'}->{$key}\n"; } } +######################################################################## +# Renaming the follow me info file, if it was successfully used. +# This can only be done, if the parameter "-d" was used with a +# directory, not a name. In this case the repeated use of parameter +# "-d" with this directory has to ignore this already successfully +# used file. +######################################################################## + +sub rename_followme_infofile +{ + my ( $filename ) = @_; + + my $newfilename = $filename; + $newfilename =~ s/follow_me_/follow_me_success_/; # including "_success" after "follow_me" + + if ( $filename ne $newfilename ) + { + my $returnvalue = rename($filename, $newfilename); + if ( $returnvalue ) { installer::logger::print_message( "\n... renamed file \"$filename\" to \"$newfilename\" ...\n" ); } + } +} + 1; diff --git a/solenv/bin/modules/installer/epmfile.pm b/solenv/bin/modules/installer/epmfile.pm index d5d489f63..9db17f5d9 100644 --- a/solenv/bin/modules/installer/epmfile.pm +++ b/solenv/bin/modules/installer/epmfile.pm @@ -2247,26 +2247,43 @@ sub determine_rpm_version { my $rpmversion = 0; my $rpmout = ""; + my $systemcall = ""; + + # my $systemcall = "rpm --version |"; + # "rpm --version" has problems since LD_LIBRARY_PATH was removed. Therefore the content of $RPM has to be called. + # "rpm --version" and "rpmbuild --version" have the same output. Therefore $RPM can be used. Its value + # is saved in $installer::globals::rpm + + if ( $installer::globals::rpm ne "" ) + { + $systemcall = "$installer::globals::rpm --version |"; + } + else + { + $systemcall = "rpm --version |"; + } - my $systemcall = "rpm --version |"; open (RPM, "$systemcall"); $rpmout = <RPM>; close (RPM); - $rpmout =~ s/\s*$//g; + if ( $rpmout ne "" ) + { + $rpmout =~ s/\s*$//g; - my $infoline = "Systemcall: $systemcall\n"; - push( @installer::globals::logfileinfo, $infoline); + 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"; } + if ( $rpmout eq "" ) { $infoline = "ERROR: Could not find file \"rpm\" !\n"; } + else { $infoline = "Success: rpm version: $rpmout\n"; } - push( @installer::globals::logfileinfo, $infoline); + 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"); } + 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; } @@ -2524,6 +2541,7 @@ sub create_packages_without_epm installer::logger::print_message( "... $systemcall ...\n" ); my $maxrpmcalls = 3; + my $rpm_failed = 0; for ( my $i = 1; $i <= $maxrpmcalls; $i++ ) { @@ -2540,7 +2558,8 @@ sub create_packages_without_epm for ( my $j = 0; $j <= $#rpmoutput; $j++ ) { - if ( $i < $maxrpmcalls ) { $rpmoutput[$j] =~ s/\bERROR\b/PROBLEM/ig; } + # if ( $i < $maxrpmcalls ) { $rpmoutput[$j] =~ s/\bERROR\b/PROBLEM/ig; } + $rpmoutput[$j] =~ s/\bERROR\b/PROBLEM/ig; push( @installer::globals::logfileinfo, "$rpmoutput[$j]"); } @@ -2548,17 +2567,65 @@ sub create_packages_without_epm { $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"); } + $rpm_failed = 1; } else { installer::logger::print_message( "Success (Try $i): \"$systemcall\"\n" ); $infoline = "Success: Executed \"$systemcall\" successfully!\n"; push( @installer::globals::logfileinfo, $infoline); + $rpm_failed = 0; last; } } - } + + if ( $rpm_failed ) + { + # Because of the problems with LD_LIBARY_PATH, a direct call of local "rpm" or "rpmbuild" might be successful + my $rpmprog = ""; + if ( -f "/usr/bin/rpmbuild" ) { $rpmprog = "/usr/bin/rpmbuild"; } + elsif ( -f "/usr/bin/rpm" ) { $rpmprog = "/usr/bin/rpm"; } + + if ( $rpmprog ne "" ) + { + installer::logger::print_message( "... $rpmprog ...\n" ); + + my $helpersystemcall = "$rpmprog -bb $specfilename --target $target $buildrootstring 2\>\&1 |"; + + my @helperrpmoutput = (); + + open (RPM, "$helpersystemcall"); + while (<RPM>) {push(@helperrpmoutput, $_); } + close (RPM); + + my $helperreturnvalue = $?; # $? contains the return value of the systemcall + + $infoline = "\nLast try: Using $rpmprog directly (problem with LD_LIBARY_PATH)\n"; + push( @installer::globals::logfileinfo, $infoline); + + $infoline = "\nSystemcall: $helpersystemcall\n"; + push( @installer::globals::logfileinfo, $infoline); + + for ( my $j = 0; $j <= $#helperrpmoutput; $j++ ) { push( @installer::globals::logfileinfo, "$helperrpmoutput[$j]"); } + + if ($helperreturnvalue) + { + $infoline = "Could not execute \"$helpersystemcall\"!\n"; + push( @installer::globals::logfileinfo, $infoline); + } + else + { + installer::logger::print_message( "Success: \"$helpersystemcall\"\n" ); + $infoline = "Success: Executed \"$helpersystemcall\" successfully!\n"; + push( @installer::globals::logfileinfo, $infoline); + $rpm_failed = 0; + } + } + + # Now it is really time to exit this packaging process, if the error still occurs + if ( $rpm_failed ) { installer::exiter::exit_program("ERROR: \"$systemcall\"!", "create_packages_without_epm"); } + } + } } ################################################# diff --git a/solenv/bin/modules/installer/followme.pm b/solenv/bin/modules/installer/followme.pm index a38d40f4f..179d56ad1 100644 --- a/solenv/bin/modules/installer/followme.pm +++ b/solenv/bin/modules/installer/followme.pm @@ -144,13 +144,25 @@ sub read_followme_info my $line = ${$filecontent}[$i]; if ( $line =~ /^\s*finalinstalldir:\s*(.*?)\s*$/ ) { $finalinstalldir = $1; } + if( $^O =~ /cygwin/i ) { $finalinstalldir =~ s/\\/\//; } + if (( $^O =~ /MSWin/i ) && ( $ENV{'USE_SHELL'} eq "4nt" )) { $finalinstalldir =~ s/\//\\/; } if ( $line =~ /^\s*downloadname:\s*(.*?)\s*$/ ) { $downloadname = $1; } if ( $line =~ /^\s*currentinstallnumber:\s*(.*?)\s*$/ ) { $currentinstallnumber = $1; } if ( $line =~ /^\s*loggingdir:\s*(.*?)\s*$/ ) { $loggingdir = $1; } + if( $^O =~ /cygwin/i ) { $loggingdir =~ s/\\/\//; } + if (( $^O =~ /MSWin/i ) && ( $ENV{'USE_SHELL'} eq "4nt" )) { $loggingdir =~ s/\//\\/; } if ( $line =~ /^\s*installlogdir:\s*(.*?)\s*$/ ) { $installlogdir = $1; } + if( $^O =~ /cygwin/i ) { $installlogdir =~ s/\\/\//; } + if (( $^O =~ /MSWin/i ) && ( $ENV{'USE_SHELL'} eq "4nt" )) { $installlogdir =~ s/\//\\/; } if ( $line =~ /^\s*languagestring:\s*(.*?)\s*$/ ) { $languagestring = $1; } if ( $line =~ /^\s*languagesarray:\s*(.*?)\s*$/ ) { push(@languagesarray, $1); } - if ( $line =~ /^\s*includepatharray:\s*(.*?)\s*$/ ) { push(@includepatharray, $1 . "\n"); } + if ( $line =~ /^\s*includepatharray:\s*(.*?)\s*$/ ) + { + my $path = $1; + if( $^O =~ /cygwin/i ) { $path =~ s/\\/\//; } + if (( $^O =~ /MSWin/i ) && ( $ENV{'USE_SHELL'} eq "4nt" )) { $path =~ s/\//\\/; } + push(@includepatharray, $path . "\n"); + } if ( $line =~ /^\s*allvariableshash:\s*(.*?)\s*:\s*(.*?)\s*$/ ) { $allvariableshash{$1} = $2; } if ( $line =~ /^\s*globals:(.*?)\s*:\s*(.*?)\s*$/ ) { @@ -176,8 +188,14 @@ sub read_followme_info if ( $name eq "issolaris" ) { $installer::globals::issolaris = $value; } if ( $name eq "islinux" ) { $installer::globals::islinux = $value; } if ( $name eq "unpackpath" ) { $installer::globals::unpackpath = $value; } + if( $^O =~ /cygwin/i ) { $installer::globals::unpackpath =~ s/\\/\//; } + if (( $^O =~ /MSWin/i ) && ( $ENV{'USE_SHELL'} eq "4nt" )) { $installer::globals::unpackpath =~ s/\//\\/; } if ( $name eq "idttemplatepath" ) { $installer::globals::idttemplatepath = $value; } + if( $^O =~ /cygwin/i ) { $installer::globals::idttemplatepath =~ s/\\/\//; } + if (( $^O =~ /MSWin/i ) && ( $ENV{'USE_SHELL'} eq "4nt" )) { $installer::globals::idttemplatepath =~ s/\//\\/; } if ( $name eq "idtlanguagepath" ) { $installer::globals::idtlanguagepath = $value; } + if( $^O =~ /cygwin/i ) { $installer::globals::idtlanguagepath =~ s/\\/\//; } + if (( $^O =~ /MSWin/i ) && ( $ENV{'USE_SHELL'} eq "4nt" )) { $installer::globals::idtlanguagepath =~ s/\//\\/; } if ( $name eq "logfilename" ) { $installer::globals::logfilename = $value; } if ( $name eq "product" ) { $installer::globals::product = $value; } if ( $name eq "patch" ) { $installer::globals::patch = $value; } diff --git a/solenv/bin/modules/installer/globals.pm b/solenv/bin/modules/installer/globals.pm index c35e12358..9b4e15317 100644 --- a/solenv/bin/modules/installer/globals.pm +++ b/solenv/bin/modules/installer/globals.pm @@ -242,6 +242,11 @@ BEGIN $exitlog = ""; $globalinfo_copied = 0; $quiet = 0; + $nodownload = 0; + $writetotemp = 0; + $useminor = 0; + $followme_from_directory = 0; + $internal_cabinet_signing = 0; $debug = 0; $debugfilename = "debug.txt"; @@ -332,6 +337,7 @@ BEGIN $patch = 0; $patchincludepath = ""; $refresh_includepathes = 0; + $include_pathes_read = 0; $patchfilelistname = "patchfilelist.txt"; @patchfilecollector = (); $nopatchfilecollector = ""; @@ -381,6 +387,7 @@ BEGIN $uredirgid = ""; $sundirgid = ""; + %sign_extensions = ("dll" => "1", "exe" => "1", "cab" => "1"); %treestyles = ("UREDIRECTORY" => "INSTALLURE", "BASISDIRECTORY" => "INSTALLBASIS", "OFFICEDIRECTORY" => "INSTALLOFFICE"); %installlocations = ("INSTALLLOCATION" => "1", "BASISINSTALLLOCATION" => "1", "OFFICEINSTALLLOCATION" => "1", "UREINSTALLLOCATION" => "1"); %treelayername = ("UREDIRECTORY" => "URE", "BASISDIRECTORY" => "BASIS", "OFFICEDIRECTORY" => "BRAND"); @@ -473,7 +480,6 @@ BEGIN if (( $plat =~ /MSWin/i ) || (( $plat =~ /cygwin/i ) && ( $ENV{'USE_SHELL'} eq "4nt" ))) { - $unzippath = "unzip.exe"; # Has to be in the path: r:\btw\unzip.exe $zippath= "zip.exe"; # Has to be in the path: r:\btw\zip.exe $checksumfile = "so_checksum.exe"; $unopkgfile = "unopkg.exe"; @@ -500,7 +506,6 @@ BEGIN } elsif (( $plat =~ /cygwin/i ) && ( $ENV{'USE_SHELL'} ne "4nt" )) { - $unzippath = "unzip"; # Has to be in the path: /usr/bin/unzip $zippath = "zip"; # Has to be in the path: /usr/bin/zip $checksumfile = "so_checksum"; $unopkgfile = "unopkg.exe"; @@ -518,7 +523,6 @@ BEGIN } else { - $unzippath = "unzip"; # Has to be in the path: /usr/bin/unzip $zippath = "zip"; # Has to be in the path: /usr/bin/zip $checksumfile = "so_checksum"; $unopkgfile = "unopkg"; diff --git a/solenv/bin/modules/installer/simplepackage.pm b/solenv/bin/modules/installer/simplepackage.pm index 74ebe82e9..77e4b9e59 100644 --- a/solenv/bin/modules/installer/simplepackage.pm +++ b/solenv/bin/modules/installer/simplepackage.pm @@ -31,7 +31,9 @@ package installer::simplepackage; +# use Archive::Zip qw( :ERROR_CODES :CONSTANTS ); use Cwd; +use File::Copy; use installer::download; use installer::exiter; use installer::globals; @@ -85,6 +87,14 @@ sub register_extensions # $installer::globals::separator . $installer::globals::unopkgfile; my $unopkgfile = $installer::globals::unopkgfile; + + my $unopkgexists = 1; + if (( $installer::globals::languagepack ) && ( ! -f $unopkgfile )) + { + $unopkgexists = 0; + $infoline = "Language packs do not contain unopkg!\n"; + push( @installer::globals::logfileinfo, $infoline); + } # my $extensiondir = $officedir . $installer::globals::separator . "share" . # $installer::globals::separator . "extension" . @@ -94,7 +104,7 @@ sub register_extensions my $allextensions = installer::systemactions::find_file_with_file_extension("oxt", $extensiondir); - if ( $#{$allextensions} > -1) + if (( $#{$allextensions} > -1 ) && ( $unopkgexists )) { my $currentdir = cwd(); print "... current dir: $currentdir ...\n"; @@ -114,7 +124,7 @@ sub register_extensions if ( $installer::globals::iswindowsbuild ) { - if (( $^O =~ /cygwin/i ) && ( $ENV{'USE_SHELL'} ne "4nt" )) + if ( $^O =~ /cygwin/i ) { $localtemppath = $installer::globals::cyg_temppath; } @@ -135,7 +145,11 @@ sub register_extensions my @unopkgoutput = (); open (UNOPKG, $systemcall); - while (<UNOPKG>) {push(@unopkgoutput, $_); } + while (<UNOPKG>) + { + my $lastline = $_; + push(@unopkgoutput, $lastline); + } close (UNOPKG); for ( my $j = 0; $j <= $#unopkgoutput; $j++ ) { push( @installer::globals::logfileinfo, "$unopkgoutput[$j]"); } @@ -157,8 +171,11 @@ sub register_extensions } else { - $infoline = "No extensions located in directory $extensiondir.\n"; - push( @installer::globals::logfileinfo, $infoline); + if ( ! ( $#{$allextensions} > -1 )) + { + $infoline = "No extensions located in directory $extensiondir.\n"; + push( @installer::globals::logfileinfo, $infoline); + } } chdir($from); @@ -180,21 +197,27 @@ sub create_package my $tempdir = $installdir . "_temp" . "." . $pid; my $systemcall = ""; my $from = ""; + my $makesystemcall = 1; my $return_to_start = 0; installer::systemactions::rename_directory($installdir, $tempdir); # creating new directory with original name installer::systemactions::create_directory($installdir); - my $archive = $installdir . $installer::globals::separator . $packagename . $installer::globals::archiveformat; + my $archive = $installdir . $installer::globals::separator . $packagename . $installer::globals::archiveformat; if ( $archive =~ /zip$/ ) { $from = cwd(); $return_to_start = 1; - chdir($tempdir); + chdir($tempdir); $systemcall = "$installer::globals::zippath -qr $archive ."; - # $systemcall = "$installer::globals::zippath -r $archive ."; + + # Using Archive::Zip fails because of very long path names below "share/uno_packages/cache" + # my $packzip = Archive::Zip->new(); + # $packzip->addTree("."); # after changing into $tempdir + # $packzip->writeToFileNamed($archive); + # $makesystemcall = 0; } elsif ( $archive =~ /dmg$/ ) { @@ -234,20 +257,23 @@ sub create_package $systemcall = "cd $tempdir; $ldpreloadstring tar -cf - . | gzip > $archive"; } - print "... $systemcall ...\n"; - my $returnvalue = system($systemcall); - my $infoline = "Systemcall: $systemcall\n"; - push( @installer::globals::logfileinfo, $infoline); - - if ($returnvalue) + if ( $makesystemcall ) { - $infoline = "ERROR: Could not execute \"$systemcall\"!\n"; - push( @installer::globals::logfileinfo, $infoline); - } - else - { - $infoline = "Success: Executed \"$systemcall\" successfully!\n"; + 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 ( $return_to_start ) { chdir($from); } @@ -319,7 +345,20 @@ sub create_simple_package if ( $onedir->{'HostName'} ) { my $destdir = $subfolderdir . $installer::globals::separator . $onedir->{'HostName'}; - if ( ! -d $destdir ) { installer::systemactions::create_directory_structure($destdir); } + if ( ! -d $destdir ) + { + if ( $^O =~ /cygwin/i ) # Cygwin performance check + { + $infoline = "Try to create directory $destdir\n"; + push(@installer::globals::logfileinfo, $infoline); + # Directories in $dirsref are sorted and all parents were added -> "mkdir" works without parent creation! + if ( ! ( -d $destdir )) { mkdir($destdir, 0775); } + } + else + { + installer::systemactions::create_directory_structure($destdir); + } + } } } @@ -345,22 +384,26 @@ sub create_simple_package $source =~ s/\$\$/\$/; $destination =~ s/\$\$/\$/; - installer::systemactions::copy_one_file($source, $destination); - - if (( ! $installer::globals::iswindowsbuild ) || - (( $^O =~ /cygwin/i ) && ( $ENV{'USE_SHELL'} ne "4nt" ))) + if ( $^O =~ /cygwin/i ) # Cygwin performance, do not use copy_one_file. "chmod -R" at the end { - my $unixrights = ""; - if ( $onefile->{'UnixRights'} ) + my $copyreturn = copy($source, $destination); + + if ($copyreturn) { - $unixrights = $onefile->{'UnixRights'}; - - # special unix rights "555" on cygwin - if (( $^O =~ /cygwin/i ) && ( $ENV{'USE_SHELL'} ne "4nt" ) && ( $unixrights =~ /444/ )) { $unixrights = "555"; } - - my $localcall = "$installer::globals::wrapcmd chmod $unixrights \'$destination\' \>\/dev\/null 2\>\&1"; - system($localcall); + $infoline = "Copy: $source to $destination\n"; + $returnvalue = 1; } + else + { + $infoline = "ERROR: Could not copy $source to $destination\n"; + $returnvalue = 0; + } + + push(@installer::globals::logfileinfo, $infoline); + } + else + { + installer::systemactions::copy_one_file($source, $destination); } } @@ -395,7 +438,18 @@ sub create_simple_package $infoline = "Creating Unix link: \"ln -sf $target $destination\"\n"; push(@installer::globals::logfileinfo, $infoline); } + + # Setting privileges for cygwin globally + + if ( $^O =~ /cygwin/i ) + { + installer::logger::print_message( "... changing privileges in $subfolderdir ...\n" ); + installer::logger::include_header_into_logfile("Changing privileges in $subfolderdir:"); + my $localcall = "chmod -R 755 " . "\"" . $subfolderdir . "\""; + system($localcall); + } + # Registering the extensions installer::logger::print_message( "... registering extensions ...\n" ); diff --git a/solenv/bin/modules/installer/systemactions.pm b/solenv/bin/modules/installer/systemactions.pm index 951a0167d..57ba2124b 100644 --- a/solenv/bin/modules/installer/systemactions.pm +++ b/solenv/bin/modules/installer/systemactions.pm @@ -1516,7 +1516,7 @@ sub remove_complete_directory # try to remove empty directory my $returnvalue = rmdir $directory; - + if ( ! $returnvalue ) { $infoline = "Warning: Problem with removing empty dir $directory\n"; @@ -1640,4 +1640,41 @@ sub read_complete_directory } } +############################################################## +# Reading all files from a directory and its subdirectories +# Version 2 +############################################################## + +sub read_full_directory { + my ( $currentdir, $pathstring, $collector ) = @_; + my $item; + my $fullname; + local *DH; + + unless (opendir(DH, $currentdir)) + { + return; + } + while (defined ($item = readdir(DH))) + { + next if($item eq "." or $item eq ".."); + $fullname = $currentdir . $installer::globals::separator . $item; + my $sep = ""; + if ( $pathstring ne "" ) { $sep = $installer::globals::separator; } + + if( -d $fullname) + { + my $newpathstring = $pathstring . $sep . $item; + read_full_directory($fullname, $newpathstring, $collector) if(-d $fullname); + } + else + { + my $content = $pathstring . $sep . $item; + push(@{$collector}, $content); + } + } + closedir(DH); + return +} + 1; diff --git a/solenv/bin/modules/installer/windows/admin.pm b/solenv/bin/modules/installer/windows/admin.pm index 6ae6c7d0b..f5026bdb2 100644 --- a/solenv/bin/modules/installer/windows/admin.pm +++ b/solenv/bin/modules/installer/windows/admin.pm @@ -37,6 +37,7 @@ use installer::files; use installer::globals; use installer::pathanalyzer; use installer::systemactions; +use installer::worker; use installer::windows::idtglobal; ################################################################################# @@ -51,6 +52,19 @@ sub unpack_cabinet_file push( @installer::globals::logfileinfo, $infoline); my $expandfile = "expand.exe"; # Has to be in the path + + # expand.exe has to be located in the system directory. + # Cygwin has another tool expand.exe, that converts tabs to spaces. This cannot be used of course. + # But this wrong expand.exe is typically in the PATH before this expand.exe, to unpack + # cabinet files. + + if ( $^O =~ /cygwin/i ) + { + $expandfile = $ENV{'SYSTEMROOT'} . "/system32/expand.exe"; # Has to be located in the systemdirectory + $expandfile =~ s/\\/\//; + if ( ! -f $expandfile ) { exit_program("ERROR: Did not find file $expandfile in the Windows system folder!"); } + } + my $expandlogfile = $unpackdir . $installer::globals::separator . "expand.log"; # exclude cabinet file @@ -60,7 +74,9 @@ sub unpack_cabinet_file if ( $^O =~ /cygwin/i ) { my $localunpackdir = qx{cygpath -w "$unpackdir"}; $localunpackdir =~ s/\\/\\\\/g; - $systemcall = $expandfile . " " . $cabfilename . " -F:\\\* " . $localunpackdir; + $cabfilename =~ s/\\/\\\\/g; + $cabfilename =~ s/\s*$//g; + $systemcall = $expandfile . " " . $cabfilename . " -F:\* " . $localunpackdir; } else { @@ -151,10 +167,34 @@ sub extract_tables_from_pcpfile my $infoline = ""; my $systemcall = ""; my $returnvalue = ""; + + my $localfullmsidatabasepath = $fullmsidatabasepath; # Export of all tables by using "*" + + if ( $^O =~ /cygwin/i ) { + # Copying the msi database locally guarantees the format of the directory. + # Otherwise it is defined in the file of UPDATE_DATABASE_LISTNAME + + my $msifilename = $localfullmsidatabasepath; + installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$msifilename); + my $destdatabasename = $workdir . $installer::globals::separator . $msifilename; + installer::systemactions::copy_one_file($localfullmsidatabasepath, $destdatabasename); + $localfullmsidatabasepath = $destdatabasename; + + chomp( $localfullmsidatabasepath = qx{cygpath -w "$localfullmsidatabasepath"} ); + chomp( $workdir = qx{cygpath -w "$workdir"} ); + + # msidb.exe really wants backslashes. (And double escaping because system() expands the string.) + $localfullmsidatabasepath =~ s/\\/\\\\/g; + $workdir =~ s/\\/\\\\/g; + + # and if there are still slashes, they also need to be double backslash + $localfullmsidatabasepath =~ s/\//\\\\/g; + $workdir =~ s/\//\\\\/g; + } - $systemcall = $msidb . " -d " . $fullmsidatabasepath . " -f " . $workdir . " -e $tablelist"; + $systemcall = $msidb . " -d " . $localfullmsidatabasepath . " -f " . $workdir . " -e $tablelist"; $returnvalue = system($systemcall); $infoline = "Systemcall: $systemcall\n"; @@ -164,7 +204,7 @@ sub extract_tables_from_pcpfile { $infoline = "ERROR: Could not execute $systemcall !\n"; push( @installer::globals::logfileinfo, $infoline); - installer::exiter::exit_program("ERROR: Could not exclude tables from pcp file: $fullmsidatabasepath !", "extract_tables_from_pcpfile"); + installer::exiter::exit_program("ERROR: Could not exclude tables from pcp file: $localfullmsidatabasepath !", "extract_tables_from_pcpfile"); } else { @@ -671,8 +711,17 @@ sub write_sis_info my $wordcount = 4; # Unpacked files my $lastprinted = get_sis_time_string(); my $lastsavedby = "Installer"; + + my $localmsidatabase = $msidatabase; + + if( $^O =~ /cygwin/i ) + { + $localmsidatabase = qx{cygpath -w "$localmsidatabase"}; + $localmsidatabase =~ s/\\/\\\\/g; + $localmsidatabase =~ s/\s*$//g; + } - $systemcall = $msiinfo . " " . "\"" . $msidatabase . "\"" . " -w " . $wordcount . " -s " . "\"" . $lastprinted . "\"" . " -l $lastsavedby"; + $systemcall = $msiinfo . " " . "\"" . $localmsidatabase . "\"" . " -w " . $wordcount . " -s " . "\"" . $lastprinted . "\"" . " -l $lastsavedby"; push(@installer::globals::logfileinfo, $systemcall); $returnvalue = system($systemcall); @@ -706,7 +755,13 @@ sub make_admin_install # Unpack all cab files into $helperdir, cab files must be located next to msi database my $installdir = $databasepath; + + if ( $^O =~ /cygwin/i ) { $installdir =~ s/\\/\//g; } # backslash to slash + installer::pathanalyzer::get_path_from_fullqualifiedname(\$installdir); + + if ( $^O =~ /cygwin/i ) { $installdir =~ s/\//\\/g; } # slash to backslash + my $databasefilename = $databasepath; installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$databasefilename); @@ -720,7 +775,15 @@ sub make_admin_install for ( my $i = 0; $i <= $#{$cabfiles}; $i++ ) { - my $cabfile = $installdir . $installer::globals::separator . ${$cabfiles}[$i]; + my $cabfile = ""; + if ( $^O =~ /cygwin/i ) + { + $cabfile = $installdir . ${$cabfiles}[$i]; + } + else + { + $cabfile = $installdir . $installer::globals::separator . ${$cabfiles}[$i]; + } unpack_cabinet_file($cabfile, $unpackdir); } diff --git a/solenv/bin/modules/installer/windows/idtglobal.pm b/solenv/bin/modules/installer/windows/idtglobal.pm index 6c7d99c03..81f6130ac 100644 --- a/solenv/bin/modules/installer/windows/idtglobal.pm +++ b/solenv/bin/modules/installer/windows/idtglobal.pm @@ -1381,7 +1381,7 @@ sub add_custom_action_to_install_table my $line = $actionname . "\t" . $actioncondition . "\t" . $actionposition . "\n"; push(@{$installtable}, $line); - $infoline = "Added $actionname CustomAction into table $customactionidttablename (NO_FILE has been set)\n"; + $infoline = "Added $actionname CustomAction into table $installtablename (NO_FILE has been set)\n"; push(@installer::globals::logfileinfo, $infoline); return; } @@ -2089,7 +2089,7 @@ sub get_customaction_position { my $line = ${$sequencetable}[$i]; - if ( $line =~ /^\s*(\w+)\t.*\t\s*(\d+)\s$/ ) # matching only, if position is a number! + if ( $line =~ /^\s*([\w\.]+)\t.*\t\s*(\d+)\s$/ ) # matching only, if position is a number! { my $compareaction = $1; my $localposition = $2; @@ -2123,7 +2123,7 @@ sub set_positions_in_table for ( my $i = 0; $i <= $#{$sequencetable}; $i++ ) { - if ( ${$sequencetable}[$i] =~ /^\s*(\w+)\t.*\t\s*POSITIONTEMPLATE_end\s*$/ ) + if ( ${$sequencetable}[$i] =~ /^\s*([\w\.]+)\t.*\t\s*POSITIONTEMPLATE_end\s*$/ ) { my $customaction = $1; $lastposition = $lastposition + 25; @@ -2150,7 +2150,7 @@ sub set_positions_in_table for ( my $i = 0; $i <= $#{$sequencetable}; $i++ ) { - if ( ${$sequencetable}[$i] =~ /^\s*(\w+)\t.*\t\s*(POSITIONTEMPLATE_.*?)\s*$/ ) + if ( ${$sequencetable}[$i] =~ /^\s*([\w\.]+)\t.*\t\s*(POSITIONTEMPLATE_.*?)\s*$/ ) { my $onename = $1; my $templatename = $2; @@ -2208,7 +2208,7 @@ sub set_positions_in_table for ( my $i = 0; $i <= $#{$sequencetable}; $i++ ) { - if ( ${$sequencetable}[$i] =~ /^\s*(\w+)\t.*\t\s*(POSITIONTEMPLATE_.*?)\s*$/ ) + if ( ${$sequencetable}[$i] =~ /^\s*([\w\.]+)\t.*\t\s*(POSITIONTEMPLATE_.*?)\s*$/ ) { my $customactionname = $1; my $fulltemplate = $2; diff --git a/solenv/bin/modules/installer/windows/msiglobal.pm b/solenv/bin/modules/installer/windows/msiglobal.pm index ec6f679a9..d7b5c6759 100644 --- a/solenv/bin/modules/installer/windows/msiglobal.pm +++ b/solenv/bin/modules/installer/windows/msiglobal.pm @@ -1977,9 +1977,10 @@ sub set_msiproductversion { if ( $allvariables->{'PACKAGEVERSION'} =~ /^\s*(\d+)\.(\d+)\.(\d+)\s*$/ ) { $productminor = $2; } } + $productversion = $productversion . "\." . $productminor . "\." . $installer::globals::buildid; } - + $installer::globals::msiproductversion = $productversion; # Setting $installer::globals::msimajorproductversion, to differ between old version in upgrade table @@ -2139,7 +2140,7 @@ sub read_saved_mappings while (<F>) { m/^([^\t]+)\t([^\t]+)\t((.*)\|)?([^\t]*)/; - print "AAA1: \$1: $1, \$2: $2, \$3: $3, \$4: $4, \$5: $5\n"; + print "OUT1: \$1: $1, \$2: $2, \$3: $3, \$4: $4, \$5: $5\n"; next if ("$1" eq "$5") && (!defined($3)); my $lc1 = lc($1); @@ -2216,7 +2217,7 @@ sub read_saved_mappings next if (!defined($3)); my $lc1 = lc($1); - print "AAA2: \$1: $1, \$2: $2, \$3: $3\n"; + print "OUT2: \$1: $1, \$2: $2, \$3: $3\n"; if ( exists($installer::globals::saved83dirmapping{$1}) ) { diff --git a/solenv/bin/modules/installer/windows/msp.pm b/solenv/bin/modules/installer/windows/msp.pm index 1d0b08219..ba0904e66 100644 --- a/solenv/bin/modules/installer/windows/msp.pm +++ b/solenv/bin/modules/installer/windows/msp.pm @@ -77,6 +77,13 @@ sub install_installation_sets my $olddatabase = installer::windows::admin::make_admin_install($oldinstallsetdatabasepath, $oldinstallpath); my $newdatabase = installer::windows::admin::make_admin_install($newinstallsetdatabasepath, $newinstallpath); + + if ( $^O =~ /cygwin/i ) { + $olddatabase = qx{cygpath -w "$olddatabase"}; + $olddatabase =~ s/\s*$//g; + $newdatabase = qx{cygpath -w "$newdatabase"}; + $newdatabase =~ s/\s*$//g; + } return ($olddatabase, $newdatabase); } @@ -93,10 +100,21 @@ sub extract_all_tables_from_pcpfile my $infoline = ""; my $systemcall = ""; my $returnvalue = ""; + my $extraslash = ""; # Has to be set for non-ActiveState perl + + my $localfullpcpfile = $fullpcpfilepath; + my $localworkdir = $workdir; + + if ( $^O =~ /cygwin/i ) { + # msidb.exe really wants backslashes. (And double escaping because system() expands the string.) + $localfullpcpfile =~ s/\//\\\\/g; + $localworkdir =~ s/\//\\\\/g; + $extraslash = "\\"; + } # Export of all tables by using "*" - $systemcall = $msidb . " -d " . $fullpcpfilepath . " -f " . $workdir . " -e \*"; + $systemcall = $msidb . " -d " . $localfullpcpfile . " -f " . $localworkdir . " -e " . $extraslash . "*"; $returnvalue = system($systemcall); $infoline = "Systemcall: $systemcall\n"; @@ -148,7 +166,16 @@ sub include_tables_into_pcpfile # Import of tables - $systemcall = $msidb . " -d " . $fullpcpfilepath . " -f " . $workdir . " -i " . $tables; + my $localworkdir = $workdir; + my $localfullpcpfilepath = $fullpcpfilepath; + + if ( $^O =~ /cygwin/i ) { + # msidb.exe really wants backslashes. (And double escaping because system() expands the string.) + $localfullpcpfilepath =~ s/\//\\\\/g; + $localworkdir =~ s/\//\\\\/g; + } + + $systemcall = $msidb . " -d " . $localfullpcpfilepath . " -f " . $localworkdir . " -i " . $tables; $returnvalue = system($systemcall); @@ -195,7 +222,25 @@ sub execute_msimsp if ( -f $logfilename ) { unlink $logfilename; } - $systemcall = $msimsp . " -s " . $fullpcpfilename . " -p " . $mspfilename . " -l " . $logfilename . " -f " . $msimsptemppath; + my $localfullpcpfilename = $fullpcpfilename; + my $localmspfilename = $mspfilename; + my $locallogfilename = $logfilename; + my $localmsimsptemppath = $msimsptemppath; + + if ( $^O =~ /cygwin/i ) { + # msimsp.exe really wants backslashes. (And double escaping because system() expands the string.) + $localfullpcpfilename =~ s/\//\\\\/g; + $locallogfilename =~ s/\//\\\\/g; + + $localmspfilename =~ s/\\/\\\\/g; # path already contains backslash + # $localmspfilename =~ s/\//\\\\/g; + + $localmsimsptemppath = qx{cygpath -w "$localmsimsptemppath"}; + $localmsimsptemppath =~ s/\\/\\\\/g; + $localmsimsptemppath =~ s/\s*$//g; + } + + $systemcall = $msimsp . " -s " . $localfullpcpfilename . " -p " . $localmspfilename . " -l " . $locallogfilename . " -f " . $localmsimsptemppath; installer::logger::print_message( "... $systemcall ...\n" ); $returnvalue = system($systemcall); @@ -283,6 +328,8 @@ sub set_mspfilename $databasename = $databasename . ".msp"; my $fullmspname = $mspdir . $installer::globals::separator . $databasename; + + if ( $^O =~ /cygwin/i ) { $fullmspname =~ s/\//\\/g; } return $fullmspname; } @@ -1191,6 +1238,9 @@ sub create_msp_patch installer::logger::print_message( "... copying installation set ...\n" ); my $oldinstallationsetpath = $installer::globals::updatedatabasepath; + + if ( $^O =~ /cygwin/i ) { $oldinstallationsetpath =~ s/\\/\//g; } + installer::pathanalyzer::get_path_from_fullqualifiedname(\$oldinstallationsetpath); installer::systemactions::copy_complete_directory($oldinstallationsetpath, $mspdir); diff --git a/solenv/bin/modules/installer/windows/sign.pm b/solenv/bin/modules/installer/windows/sign.pm index 26dec0109..5f1b80bb6 100644 --- a/solenv/bin/modules/installer/windows/sign.pm +++ b/solenv/bin/modules/installer/windows/sign.pm @@ -123,6 +123,11 @@ sub check_system_path # Windows : "msicert.exe", "msidb.exe", "signtool.exe" my @needed_files_in_path = ("msicert.exe", "msidb.exe", "signtool.exe"); + if ( $installer::globals::internal_cabinet_signing ) + { + push(@needed_files_in_path, "cabarc.exe"); + push(@needed_files_in_path, "makecab.exe"); + } my $onefile; my $error = 0; @@ -193,6 +198,82 @@ sub make_systemcall return $success; } +###################################################### +# Making systemcall with warning +###################################################### + +sub make_systemcall_with_warning +{ + my ($systemcall, $displaysystemcall) = @_; + + installer::logger::print_message( "... $displaysystemcall ...\n" ); + + my $success = 1; + my $returnvalue = system($systemcall); + + my $infoline = "Systemcall: $displaysystemcall\n"; + push( @installer::globals::logfileinfo, $infoline); + + if ($returnvalue) + { + $infoline = "WARNING: Could not execute \"$displaysystemcall\"!\n"; + push( @installer::globals::logfileinfo, $infoline); + $success = 0; + } + else + { + $infoline = "Success: Executed \"$displaysystemcall\" successfully!\n"; + push( @installer::globals::logfileinfo, $infoline); + } + + return $success; +} + +###################################################### +# Making systemcall with more return data +###################################################### + +sub execute_open_system_call +{ + my ( $systemcall ) = @_; + + my @openoutput = (); + my $success = 1; + + my $comspec = $ENV{COMSPEC}; + $comspec = $comspec . " -c "; + + if( $^O =~ /cygwin/i ) + { + # $comspec =~ s/\\/\\\\/g; + # $comspec = qx{cygpath -u "$comspec"}; + # $comspec =~ s/\s*$//g; + $comspec = ""; + } + + my $localsystemcall = "$comspec $systemcall 2>&1 |"; + + open( OPN, "$localsystemcall") or warn "Can't execute $localsystemcall\n"; + while (<OPN>) { push(@openoutput, $_); } + close (OPN); + + my $returnvalue = $?; # $? contains the return value of the systemcall + + if ($returnvalue) + { + $infoline = "ERROR: Could not execute \"$systemcall\"!\n"; + push( @installer::globals::logfileinfo, $infoline); + $success = 0; + } + else + { + $infoline = "Success: Executed \"$systemcall\" successfully!\n"; + push( @installer::globals::logfileinfo, $infoline); + } + + return ($success, \@openoutput); +} + ######################################################## # Reading first line of pw file. ######################################################## @@ -255,7 +336,7 @@ sub analyze_media_file # Collect all DiskIds from database table "Media". ######################################################## -sub collect_diskid +sub collect_diskid_from_media_table { my ($msidatabase, $languagestring) = @_; @@ -265,7 +346,7 @@ sub collect_diskid # Reading tables my $filename = $workdir . $installer::globals::separator . "Media.idt"; - if ( ! -f $filename ) { installer::exiter::exit_program("ERROR: Could not find required file: $filename !", "collect_diskid"); } + if ( ! -f $filename ) { installer::exiter::exit_program("ERROR: Could not find required file: $filename !", "collect_diskid_from_media_table"); } my $filecontent = installer::files::read_file($filename); my $diskidhash = analyze_media_file($filecontent); @@ -273,6 +354,34 @@ sub collect_diskid } ######################################################## +# Check, if this installation set contains +# internal cabinet files included into the msi +# database. +######################################################## + +sub check_for_internal_cabfiles +{ + my ($cabfilehash) = @_; + + my $contains_internal_cabfiles = 0; + my %allcabfileshash = (); + + foreach my $filename ( keys %{$cabfilehash} ) + { + if ( $filename =~ /^\s*\#/ ) # starting with a hash + { + $contains_internal_cabfiles = 1; + # setting real filename without hash as key and name with hash as value + my $realfilename = $filename; + $realfilename =~ s/^\s*\#//; + $allcabfileshash{$realfilename} = $filename; + } + } + + return ( $contains_internal_cabfiles, \%allcabfileshash ); +} + +######################################################## # Collecting all files in an installation set. ######################################################## @@ -289,18 +398,19 @@ sub analyze_installset_content my %allcabfileshash = (); my %allmsidatabaseshash = (); my %allfileshash = (); - my $contains_cab_file = 0; + my $contains_external_cabfiles = 0; my $msidatabase = ""; + my $contains_msidatabase = 0; for ( my $j = 0; $j <= $#sourcefiles; $j++ ) { if ( $sourcefiles[$j] =~ /\.cab\s*$/ ) { $allcabfileshash{$sourcefiles[$j]} = 1; } else { - if ( $sourcefiles[$j] =~ /jre[-\w]+.exe\s*$/ ) { next; } # no signing of java executable if ( $sourcefiles[$j] =~ /\.txt\s*$/ ) { next; } if ( $sourcefiles[$j] =~ /\.html\s*$/ ) { next; } if ( $sourcefiles[$j] =~ /\.ini\s*$/ ) { next; } + if ( $sourcefiles[$j] =~ /\.bmp\s*$/ ) { next; } if ( $sourcefiles[$j] =~ /\.msi\s*$/ ) { if ( $msidatabase eq "" ) { $msidatabase = $sourcefiles[$j]; } @@ -312,12 +422,14 @@ sub analyze_installset_content # Is there at least one cab file in the installation set? my $cabcounter = get_hash_count(\%allcabfileshash); - if ( $cabcounter > 0 ) { $contains_cab_file = 1; } + if ( $cabcounter > 0 ) { $contains_external_cabfiles = 1; } # How about a cab file without a msi database? if (( $cabcounter > 0 ) && ( $msidatabase eq "" )) { installer::exiter::exit_program("ERROR: There is no msi database in the installation set, but an external cabinet file. Path: $installsetpath !", "collect_installset_content"); } - return (\%allcabfileshash, \%allfileshash, $msidatabase, $contains_cab_file); + if ( $msidatabase ne "" ) { $contains_msidatabase = 1; } + + return (\%allcabfileshash, \%allfileshash, $msidatabase, $contains_external_cabfiles, $contains_msidatabase); } ######################################################## @@ -327,17 +439,17 @@ sub analyze_installset_content sub msicert_database { - my ($msidatabase, $allcabfiles, $languagestring) = @_; - - # exclude media table from msi database and get all diskids. - my $cabfilehash = collect_diskid($msidatabase, $languagestring); - + my ($msidatabase, $allcabfiles, $cabfilehash, $internalcabfile) = @_; + my $fullsuccess = 1; - + foreach my $cabfile ( keys %{$allcabfiles} ) { - if ( ! exists($cabfilehash->{$cabfile}) ) { installer::exiter::exit_program("ERROR: Could not determine DiskId from media table for cabinet file \"$cabfile\" !", "msicert_database"); } - my $diskid = $cabfilehash->{$cabfile}; + my $mediacabfilename = $cabfile; + if ( $internalcabfile ) { $mediacabfilename = "\#" . $mediacabfilename; } + if ( ! exists($cabfilehash->{$mediacabfilename}) ) { installer::exiter::exit_program("ERROR: Could not determine DiskId from media table for cabinet file \"$cabfile\" !", "msicert_database"); } + my $diskid = $cabfilehash->{$mediacabfilename}; + my $systemcall = "msicert.exe -d $msidatabase -m $diskid -c $cabfile -h"; $success = make_systemcall($systemcall, $systemcall); if ( ! $success ) { $fullsuccess = 0; } @@ -352,36 +464,453 @@ sub msicert_database sub sign_files { - my ( $followmeinfohash, $allfiles, $pw ) = @_; + my ( $followmeinfohash, $allfiles, $pw, $cabinternal ) = @_; my $infoline = ""; my $fullsuccess = 1; + my $maxcounter = 3; my $productname = ""; if ( $followmeinfohash->{'allvariableshash'}->{'PRODUCTNAME'} ) { $productname = "/d " . "\"$followmeinfohash->{'allvariableshash'}->{'PRODUCTNAME'}\""; } my $url = ""; - if ( $followmeinfohash->{'allvariableshash'}->{'OPENSOURCE'} == 0 ) { $url = "/du " . "\"http://www.sun.com\""; } + if (( ! exists($followmeinfohash->{'allvariableshash'}->{'OPENSOURCE'}) ) || ( $followmeinfohash->{'allvariableshash'}->{'OPENSOURCE'} == 0 )) { $url = "/du " . "\"http://www.sun.com\""; } else { $url = "/du " . "\"http://www.openoffice.org\""; } my $timestampurl = "http://timestamp.verisign.com/scripts/timestamp.dll"; - - foreach my $onefile ( keys %{$allfiles} ) + + my $pfxfilepath = $installer::globals::pfxfile; + + if( $^O =~ /cygwin/i ) { - my $systemcall = "signtool.exe sign /f \"$installer::globals::pfxfile\" /p $pw $productname $url /t \"$timestampurl\" \"$onefile\""; - my $displaysystemcall = "signtool.exe sign /f \"$installer::globals::pfxfile\" /p ***** $productname $url /t \"$timestampurl\" \"$onefile\""; - my $success = make_systemcall($systemcall, $displaysystemcall); - if ( ! $success ) { $fullsuccess = 0; } + $pfxfilepath = qx{cygpath -w "$pfxfilepath"}; + $pfxfilepath =~ s/\\/\\\\/g; + $pfxfilepath =~ s/\s*$//g; + } + + foreach my $onefile ( reverse sort keys %{$allfiles} ) + { + if ( already_certified($onefile) ) + { + $infoline = "Already certified: Skipping file $onefile\n"; + push( @installer::globals::logfileinfo, $infoline); + next; + } + + my $counter = 1; + my $success = 0; + + while (( $counter <= $maxcounter ) && ( ! $success )) + { + if ( $counter > 1 ) { installer::logger::print_message( "\n\n... repeating file $onefile ...\n" ); } + if ( $cabinternal ) { installer::logger::print_message(" Signing: $onefile\n"); } + my $systemcall = "signtool.exe sign /f \"$pfxfilepath\" /p $pw $productname $url /t \"$timestampurl\" \"$onefile\""; + my $displaysystemcall = "signtool.exe sign /f \"$pfxfilepath\" /p ***** $productname $url /t \"$timestampurl\" \"$onefile\""; + $success = make_systemcall_with_warning($systemcall, $displaysystemcall); + $counter++; + } + + if ( ! $success ) + { + $fullsuccess = 0; + installer::exiter::exit_program("ERROR: Could not sign file: $onefile!", "sign_files"); + } } return $fullsuccess; } +########################################################################## +# Lines in ddf files must not contain more than 256 characters +########################################################################## + +sub check_ddf_file +{ + my ( $ddffile, $ddffilename ) = @_; + + my $maxlength = 0; + my $maxline = 0; + my $linelength = 0; + my $linenumber = 0; + + for ( my $i = 0; $i <= $#{$ddffile}; $i++ ) + { + my $oneline = ${$ddffile}[$i]; + + $linelength = length($oneline); + $linenumber = $i + 1; + + if ( $linelength > 256 ) + { + installer::exiter::exit_program("ERROR \"$ddffilename\" line $linenumber: Lines in ddf files must not contain more than 256 characters!", "check_ddf_file"); + } + + if ( $linelength > $maxlength ) + { + $maxlength = $linelength; + $maxline = $linenumber; + } + } + + my $infoline = "Check of ddf file \"$ddffilename\": Maximum length \"$maxlength\" in line \"$maxline\" (allowed line length: 256 characters)\n"; + push( @installer::globals::logfileinfo, $infoline); +} + +################################################################# +# Setting the path, where the cab files are unpacked. +################################################################# + +sub get_cab_path +{ + my ($temppath) = @_; + + my $cabpath = "cabs_" . $$; + $cabpath = $temppath . $installer::globals::separator . $cabpath; + if ( ! -d $cabpath ) { installer::systemactions::create_directory($cabpath); } + + return $cabpath; +} + +################################################################# +# Exclude all cab files from the msi database. +################################################################# + +sub extract_cabs_from_database +{ + my ($msidatabase, $allcabfiles) = @_; + + installer::logger::include_header_into_logfile("Extracting cabs from msi database"); + + my $infoline = ""; + my $fullsuccess = 1; + my $msidb = "msidb.exe"; # Has to be in the path + + if ( $ENV{'USE_SHELL'} ne "4nt" ) { + # msidb.exe really wants backslashes. (And double escaping because system() expands the string.) + $msidatabase =~ s/\//\\\\/g; + } + + foreach my $onefile ( keys %{$allcabfiles} ) + { + my $systemcall = $msidb . " -d " . $msidatabase . " -x " . $onefile; + my $success = make_systemcall($systemcall, $systemcall); + if ( ! $success ) { $fullsuccess = 0; } + + # and removing the stream from the database + $systemcall = $msidb . " -d " . $msidatabase . " -k " . $onefile; + $success = make_systemcall($systemcall, $systemcall); + if ( ! $success ) { $fullsuccess = 0; } + } + + return $fullsuccess; +} + +################################################################# +# Include cab files into the msi database. +################################################################# + +sub include_cabs_into_database +{ + my ($msidatabase, $allcabfiles) = @_; + + installer::logger::include_header_into_logfile("Including cabs into msi database"); + + my $infoline = ""; + my $fullsuccess = 1; + my $msidb = "msidb.exe"; # Has to be in the path + + if ( $ENV{'USE_SHELL'} ne "4nt" ) { + # msidb.exe really wants backslashes. (And double escaping because system() expands the string.) + $msidatabase =~ s/\//\\\\/g; + } + + foreach my $onefile ( keys %{$allcabfiles} ) + { + my $systemcall = $msidb . " -d " . $msidatabase . " -a " . $onefile; + my $success = make_systemcall($systemcall, $systemcall); + if ( ! $success ) { $fullsuccess = 0; } + } + + return $fullsuccess; +} + +######################################################## +# Reading the order of the files inside the +# cabinet files. +######################################################## + +sub read_cab_file +{ + my ($cabfilename) = @_; + + installer::logger::print_message( "\n... reading cabinet file $cabfilename ...\n" ); + my $infoline = "Reading cabinet file $cabfilename\n"; + push( @installer::globals::logfileinfo, $infoline); + + my $systemcall = "cabarc.exe" . " L " . $cabfilename; + push(@logfile, "$systemcall\n"); + + my ($success, $fileorder) = execute_open_system_call($systemcall); + + my @allfiles = (); + + for ( my $i = 0; $i <= $#{$fileorder}; $i++ ) + { + my $line = ${$fileorder}[$i]; + if ( $line =~ /^\s*(.*?)\s+\d+\s+\d+\/\d+\/\d+\s+\d+\:\d+\:\d+\s+[\w-]+\s*$/ ) + { + my $filename = $1; + push(@allfiles, $filename); + } + } + + return \@allfiles; +} + +######################################################## +# Unpacking a cabinet file. +######################################################## + +sub unpack_cab_file +{ + my ($cabfilename, $temppath) = @_; + + installer::logger::print_message( "\n... unpacking cabinet file $cabfilename ...\n" ); + my $infoline = "Unpacking cabinet file $cabfilename\n"; + push( @installer::globals::logfileinfo, $infoline); + + my $dirname = $cabfilename; + $dirname =~ s/\.cab\s*$//; + my $workingpath = $temppath . $installer::globals::separator . "unpack_". $dirname . "_" . $$; + if ( ! -d $workingpath ) { installer::systemactions::create_directory($workingpath); } + + # changing into unpack directory + my $from = cwd(); + chdir($workingpath); + + my $fullcabfilename = $from . $installer::globals::separator . $cabfilename; + + if( $^O =~ /cygwin/i ) + { + $fullcabfilename = qx{cygpath -w "$fullcabfilename"}; + $fullcabfilename =~ s/\\/\\\\/g; + $fullcabfilename =~ s/\s*$//g; + } + + my $systemcall = "cabarc.exe" . " -p X " . $fullcabfilename; + $success = make_systemcall($systemcall, $systemcall); + if ( ! $success ) { installer::exiter::exit_program("ERROR: Could not unpack cabinet file: $fullcabfilename!", "unpack_cab_file"); } + + # returning to directory + chdir($from); + + return $workingpath; +} + +######################################################## +# Returning the header of a ddf file. +######################################################## + +sub get_ddf_file_header +{ + my ($ddffileref, $cabinetfile, $installdir) = @_; + + my $oneline; + my $compressionlevel = 2; + + if( $^O =~ /cygwin/i ) + { + $installdir = qx{cygpath -w "$installdir"}; + $installdir =~ s/\s*$//g; + } + + $oneline = ".Set CabinetName1=" . $cabinetfile . "\n"; + push(@{$ddffileref} ,$oneline); + $oneline = ".Set ReservePerCabinetSize=128\n"; # This reserves space for a digital signature. + push(@{$ddffileref} ,$oneline); + $oneline = ".Set MaxDiskSize=CDROM\n"; # This allows the .cab file to be as large as needed. + push(@{$ddffileref} ,$oneline); + $oneline = ".Set CompressionType=LZX\n"; + push(@{$ddffileref} ,$oneline); + $oneline = ".Set Compress=ON\n"; + push(@{$ddffileref} ,$oneline); + $oneline = ".Set CompressionLevel=$compressionlevel\n"; + push(@{$ddffileref} ,$oneline); + $oneline = ".Set Cabinet=ON\n"; + push(@{$ddffileref} ,$oneline); + $oneline = ".Set DiskDirectoryTemplate=" . $installdir . "\n"; + push(@{$ddffileref} ,$oneline); +} + +######################################################## +# Writing content into ddf file. +######################################################## + +sub put_all_files_into_ddffile +{ + my ($ddffile, $allfiles, $workingpath) = @_; + + $workingpath =~ s/\//\\/g; + + for ( my $i = 0; $i <= $#{$allfiles}; $i++ ) + { + my $filename = ${$allfiles}[$i]; + if( $^O =~ /cygwin/i ) { $filename =~ s/\//\\/g; } # Backslash for Cygwin! + if ( ! -f $filename ) { installer::exiter::exit_program("ERROR: Could not find file: $filename!", "put_all_files_into_ddffile"); } + my $infoline = "\"" . $filename . "\"" . " " . ${$allfiles}[$i] . "\n"; + push( @{$ddffile}, $infoline); + } +} + +######################################################## +# Packing a cabinet file. +######################################################## + +sub do_pack_cab_file +{ + my ($cabfilename, $allfiles, $workingpath, $temppath) = @_; + + installer::logger::print_message( "\n... packing cabinet file $cabfilename ...\n" ); + my $infoline = "Packing cabinet file $cabfilename\n"; + push( @installer::globals::logfileinfo, $infoline); + + if ( -f $cabfilename ) { unlink($cabfilename); } # removing cab file + if ( -f $cabfilename ) { installer::exiter::exit_program("ERROR: Failed to remove file: $cabfilename!", "do_pack_cab_file"); } + + # generate ddf file for makecab.exe + my @ddffile = (); + + my $dirname = $cabfilename; + $dirname =~ s/\.cab\s*$//; + my $ddfpath = $temppath . $installer::globals::separator . "ddf_". $dirname . "_" . $$; + + my $ddffilename = $cabfilename; + $ddffilename =~ s/.cab/.ddf/; + $ddffilename = $ddfpath . $installer::globals::separator . $ddffilename; + + if ( ! -d $ddfpath ) { installer::systemactions::create_directory($ddfpath); } + + my $from = cwd(); + + chdir($workingpath); # changing into the directory with the unpacked files + + get_ddf_file_header(\@ddffile, $cabfilename, $from); + put_all_files_into_ddffile(\@ddffile, $allfiles, $workingpath); + # lines in ddf files must not be longer than 256 characters + check_ddf_file(\@ddffile, $ddffilename); + + installer::files::save_file($ddffilename, \@ddffile); + + if( $^O =~ /cygwin/i ) + { + $ddffilename = qx{cygpath -w "$ddffilename"}; + $ddffilename =~ s/\\/\\\\/g; + $ddffilename =~ s/\s*$//g; + } + + my $systemcall = "makecab.exe /V1 /F " . $ddffilename; + my $success = make_systemcall($systemcall, $systemcall); + if ( ! $success ) { installer::exiter::exit_program("ERROR: Could not pack cabinet file!", "do_pack_cab_file"); } + + chdir($from); + + return ($success); +} + +######################################################## +# Extraction the file extension from a file +######################################################## + +sub get_extension +{ + my ( $file ) = @_; + + my $extension = ""; + + if ( $file =~ /^\s*(.*)\.(\w+?)\s*$/ ) { $extension = $2; } + + return $extension; +} + +######################################################## +# Checking, if a file already contains a certificate. +# This must not be overwritten. +######################################################## + +sub already_certified +{ + my ( $filename ) = @_; + + my $success = 1; + my $is_certified = 0; + + my $systemcall = "signtool.exe verify /q /pa \"$filename\""; + my $returnvalue = system($systemcall); + + if ( $returnvalue ) { $success = 0; } + + # my $success = make_systemcall($systemcall, $systemcall); + + if ( $success ) + { + $is_certified = 1; + installer::logger::print_message( "... already certified -> skipping $filename ...\n" ); + } + + return $is_certified; +} + +######################################################## +# Signing the files, that are included into +# cabinet files. +######################################################## + +sub sign_files_in_cabinet_files +{ + my ( $followmeinfohash, $allcabfiles, $pw, $temppath ) = @_; + + my $complete_success = 1; + my $from = cwd(); + + foreach my $cabfilename ( keys %{$allcabfiles} ) + { + my $success = 1; + + # saving order of files in cab file + my $fileorder = read_cab_file($cabfilename); + + # unpack into $working path + my $workingpath = unpack_cab_file($cabfilename, $temppath); + + chdir($workingpath); + + # sign files + my %allfileshash = (); + foreach my $onefile ( @{$fileorder} ) + { + my $extension = get_extension($onefile); + if ( exists( $installer::globals::sign_extensions{$extension} ) ) + { + $allfileshash{$onefile} = 1; + } + } + $success = sign_files($followmeinfohash, \%allfileshash, $pw, 1); + if ( ! $success ) { $complete_success = 0; } + + chdir($from); + + # pack into new directory + do_pack_cab_file($cabfilename, $fileorder, $workingpath, $temppath); + } + + return $complete_success; +} + ######################################################## # Signing an existing Windows installation set. ######################################################## sub sign_install_set { - my ($followmeinfohash, $make_copy) = @_; + my ($followmeinfohash, $make_copy, $temppath) = @_; my $installsetpath = $followmeinfohash->{'finalinstalldir'}; @@ -404,24 +933,66 @@ sub sign_install_set else { $installsetpath = rename_install_set($installsetpath); } # collecting all files in the installation set - my ($allcabfiles, $allfiles, $msidatabase, $contains_cab_file) = analyze_installset_content($installsetpath); + my ($allcabfiles, $allfiles, $msidatabase, $contains_external_cabfiles, $contains_msidatabase) = analyze_installset_content($installsetpath); # changing into installation set my $from = cwd(); + my $fullmsidatabase = $installsetpath . $installer::globals::separator . $msidatabase; + + if( $^O =~ /cygwin/i ) + { + $fullmsidatabase = qx{cygpath -w "$fullmsidatabase"}; + $fullmsidatabase =~ s/\\/\\\\/g; + $fullmsidatabase =~ s/\s*$//g; + } + chdir($installsetpath); - # Warning: There might be a problem with very big cabinet files - # signing all external cab files first - if ( $contains_cab_file ) + if ( $contains_msidatabase ) { - $success = sign_files($followmeinfohash, $allcabfiles, $pw); - if ( ! $success ) { $complete_success = 0; } - $success = msicert_database($msidatabase, $allcabfiles, $followmeinfohash->{'languagestring'}); - if ( ! $success ) { $complete_success = 0; } + # exclude media table from msi database and get all diskids. + my $cabfilehash = collect_diskid_from_media_table($msidatabase, $followmeinfohash->{'languagestring'}); + + # Check, if there are internal cab files + my ( $contains_internal_cabfiles, $all_internal_cab_files) = check_for_internal_cabfiles($cabfilehash); + + if ( $contains_internal_cabfiles ) + { + my $cabpath = get_cab_path($temppath); + chdir($cabpath); + + # Exclude all cabinet files from database + $success = extract_cabs_from_database($fullmsidatabase, $all_internal_cab_files); + if ( ! $success ) { $complete_success = 0; } + + if ( $installer::globals::internal_cabinet_signing ) { sign_files_in_cabinet_files($followmeinfohash, $all_internal_cab_files, $pw, $temppath); } + + $success = sign_files($followmeinfohash, $all_internal_cab_files, $pw, 0); + if ( ! $success ) { $complete_success = 0; } + $success = msicert_database($fullmsidatabase, $all_internal_cab_files, $cabfilehash, 1); + if ( ! $success ) { $complete_success = 0; } + + # Include all cabinet files into database + $success = include_cabs_into_database($fullmsidatabase, $all_internal_cab_files); + if ( ! $success ) { $complete_success = 0; } + chdir($installsetpath); + } + + # Warning: There might be a problem with very big cabinet files + # signing all external cab files first + if ( $contains_external_cabfiles ) + { + if ( $installer::globals::internal_cabinet_signing ) { sign_files_in_cabinet_files($followmeinfohash, $allcabfiles, $pw, $temppath); } + + $success = sign_files($followmeinfohash, $allcabfiles, $pw, 0); + if ( ! $success ) { $complete_success = 0; } + $success = msicert_database($msidatabase, $allcabfiles, $cabfilehash, 0); + if ( ! $success ) { $complete_success = 0; } + } } # finally all other files can be signed - $success = sign_files($followmeinfohash, $allfiles, $pw); + $success = sign_files($followmeinfohash, $allfiles, $pw, 0); if ( ! $success ) { $complete_success = 0; } # and changing back diff --git a/solenv/bin/modules/installer/windows/update.pm b/solenv/bin/modules/installer/windows/update.pm index 3af5945e4..e3a17bf5d 100644 --- a/solenv/bin/modules/installer/windows/update.pm +++ b/solenv/bin/modules/installer/windows/update.pm @@ -50,10 +50,18 @@ sub extract_all_tables_from_msidatabase my $infoline = ""; my $systemcall = ""; my $returnvalue = ""; + my $extraslash = ""; # Has to be set for non-ActiveState perl # Export of all tables by using "*" + + if ( $^O =~ /cygwin/i ) { + # msidb.exe really wants backslashes. (And double escaping because system() expands the string.) + $fulldatabasepath =~ s/\//\\\\/g; + $workdir =~ s/\//\\\\/g; + $extraslash = "\\"; + } - $systemcall = $msidb . " -d " . $fulldatabasepath . " -f " . $workdir . " -e \*"; + $systemcall = $msidb . " -d " . $fulldatabasepath . " -f " . $workdir . " -e " . $extraslash . "*"; $returnvalue = system($systemcall); $infoline = "Systemcall: $systemcall\n"; diff --git a/solenv/bin/modules/installer/worker.pm b/solenv/bin/modules/installer/worker.pm index e30e253c2..cc1b98e78 100644 --- a/solenv/bin/modules/installer/worker.pm +++ b/solenv/bin/modules/installer/worker.pm @@ -2373,7 +2373,8 @@ sub collect_all_files_from_includepathes my @sourcefiles = (); my $pathstring = ""; - installer::systemactions::read_complete_directory($includepath, $pathstring, \@sourcefiles); + # installer::systemactions::read_complete_directory($includepath, $pathstring, \@sourcefiles); + installer::systemactions::read_full_directory($includepath, $pathstring, \@sourcefiles); if ( ! ( $#sourcefiles > -1 )) { @@ -2397,6 +2398,8 @@ sub collect_all_files_from_includepathes push(@installer::globals::allincludepathes, \%allfileshash); } } + + $installer::globals::include_pathes_read = 1; installer::logger::globallog("Reading all directories: End"); push( @installer::globals::globallogfileinfo, "\n"); @@ -2681,7 +2684,6 @@ sub generate_cygwin_pathes } } - sub filter_pkgmapfile { my ($pkgmapfile) = @_; diff --git a/solenv/bin/modules/installer/xpdinstaller.pm b/solenv/bin/modules/installer/xpdinstaller.pm index 71871b20b..8eeab1867 100644 --- a/solenv/bin/modules/installer/xpdinstaller.pm +++ b/solenv/bin/modules/installer/xpdinstaller.pm @@ -573,7 +573,15 @@ sub get_size_value if ( ! $installer::globals::rpmquerycommand ) { $installer::globals::rpmquerycommand = "rpm"; } # For queries "rpm" is used, not "rpmbuild" my $systemcall = "$installer::globals::rpmquerycommand -qp --queryformat \"\[\%\{FILESIZES\}\\n\]\" $packagename 2\>\&1 |"; - my $rpmout = make_systemcall($systemcall, 0); + my ($rpmout, $error) = make_systemcall_allowing_error($systemcall, 0, 1); + # Evaluating an error, because of rpm problems with removed LD_LIBRARY_PATH + if ( $error ) + { + installer::logger::print_message( "... trying /usr/bin/rpm ...\n" ); + my $systemcall = "/usr/bin/rpm -qp --queryformat \"\[\%\{FILESIZES\}\\n\]\" $packagename 2\>\&1 |"; + ($rpmout, $error) = make_systemcall_allowing_error($systemcall, 0, 0); + if ( $error ) { installer::exiter::exit_program("ERROR: rpm failed to query package!", "get_size_value"); } + } $value = do_sum($rpmout); # adding all filesizes in bytes $value = $value/1000; @@ -692,7 +700,18 @@ sub get_fullpkgname_value # if ( ! $installer::globals::rpmquerycommand ) { installer::exiter::exit_program("ERROR: rpm not found for querying packages!", "get_fullpkgname_value"); } if ( ! $installer::globals::rpmquerycommand ) { $installer::globals::rpmquerycommand = "rpm"; } # For queries "rpm" is used, not "rpmbuild" my $systemcall = "$installer::globals::rpmquerycommand -qp $packagename |"; - my $returnarray = make_systemcall($systemcall, 0); + # my $returnarray = make_systemcall($systemcall, 0); + + my ($returnarray, $error) = make_systemcall_allowing_error($systemcall, 0, 1); + # Evaluating an error, because of rpm problems with removed LD_LIBRARY_PATH + if ( $error ) + { + installer::logger::print_message( "... trying /usr/bin/rpm ...\n" ); + my $systemcall = "/usr/bin/rpm -qp $packagename |"; + ($returnarray, $error) = make_systemcall_allowing_error($systemcall, 0, 0); + if ( $error ) { installer::exiter::exit_program("ERROR: rpm failed to query package!", "get_fullpkgname_value"); } + } + $value = ${$returnarray}[0]; installer::remover::remove_leading_and_ending_whitespaces(\$value); @@ -849,6 +868,56 @@ sub make_systemcall return \@returns; } +####################################################### +# Executing one system call +####################################################### + +sub make_systemcall_allowing_error +{ + my ( $systemcall, $logreturn, $can_fail ) = @_; + + my @returns = (); + + installer::logger::print_message( "... $systemcall ...\n" ); + + open (REG, "$systemcall"); + while (<REG>) {push(@returns, $_); } + close (REG); + + my $returnvalue = $?; # $? contains the return value of the systemcall + + my $infoline = "Systemcall: $systemcall\n"; + push( @installer::globals::logfileinfo, $infoline); + + if ( $logreturn ) + { + for ( my $j = 0; $j <= $#returns; $j++ ) { push( @installer::globals::logfileinfo, "$returns[$j]"); } + } + + if ($returnvalue) + { + if ( $can_fail ) + { + $infoline = "WARNING: Failed system call: $systemcall\n"; + push( @installer::globals::logfileinfo, $infoline); + $error_occured = 1; + } + else + { + $infoline = "ERROR: $systemcall\n"; + push( @installer::globals::logfileinfo, $infoline); + $error_occured = 1; + } + } + else + { + $infoline = "SUCCESS: $systemcall\n"; + push( @installer::globals::logfileinfo, $infoline); + } + + return (\@returns, $returnvalue); +} + ################################################### # Setting product name tag ################################################### |