You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by or...@apache.org on 2013/12/18 14:27:25 UTC
svn commit: r1551937 [15/29] - in /openoffice/branches/ooxml-osba: ./
extras/l10n/source/bg/ extras/l10n/source/de/ extras/l10n/source/nb/
extras/l10n/source/th/ main/ main/accessibility/inc/accessibility/extended/
main/accessibility/inc/accessibility/...
Modified: openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/control.pm
URL: http://svn.apache.org/viewvc/openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/control.pm?rev=1551937&r1=1551936&r2=1551937&view=diff
==============================================================================
--- openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/control.pm (original)
+++ openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/control.pm Wed Dec 18 13:27:09 2013
@@ -428,16 +428,7 @@ sub determine_ship_directory
my $shipdrive = $ENV{'SHIPDRIVE'};
- my $languagestring = $$languagesref;
-
- if (length($languagestring) > $installer::globals::max_lang_length )
- {
- my $number_of_languages = installer::systemactions::get_number_of_langs($languagestring);
- chomp(my $shorter = `echo $languagestring | md5sum | sed -e "s/ .*//g"`);
- # $languagestring = $shorter;
- my $id = substr($shorter, 0, 8); # taking only the first 8 digits
- $languagestring = "lang_" . $number_of_languages . "_id_" . $id;
- }
+ my $languagestring = installer::languages::get_language_directory_name($$languagesref);
my $productstring = $installer::globals::product;
my $productsubdir = "";
Modified: openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/converter.pm
URL: http://svn.apache.org/viewvc/openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/converter.pm?rev=1551937&r1=1551936&r2=1551937&view=diff
==============================================================================
--- openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/converter.pm (original)
+++ openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/converter.pm Wed Dec 18 13:27:09 2013
@@ -309,14 +309,13 @@ sub copy_collector
my @newcollector = ();
- for ( my $i = 0; $i <= $#{$oldcollector}; $i++ )
+ foreach my $oldhash (@$oldcollector)
{
my %newhash = ();
- my $key;
- foreach $key (keys %{${$oldcollector}[$i]})
+ while (my ($key, $value) = each %$oldhash)
{
- $newhash{$key} = ${$oldcollector}[$i]->{$key};
+ $newhash{$key} = $value;
}
push(@newcollector, \%newhash);
Modified: openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/download.pm
URL: http://svn.apache.org/viewvc/openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/download.pm?rev=1551937&r1=1551936&r2=1551937&view=diff
==============================================================================
--- openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/download.pm (original)
+++ openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/download.pm Wed Dec 18 13:27:09 2013
@@ -32,6 +32,8 @@ use installer::pathanalyzer;
use installer::remover;
use installer::systemactions;
+use strict;
+
BEGIN { # This is needed so that cygwin's perl evaluates ACLs
# (needed for correctly evaluating the -x test.)
if( $^O =~ /cygwin/i ) {
@@ -157,7 +159,7 @@ sub call_md5sum
{
my ($filename) = @_;
- $md5sumfile = "/usr/bin/md5sum";
+ my $md5sumfile = "/usr/bin/md5sum";
if ( ! -f $md5sumfile ) { installer::exiter::exit_program("ERROR: No file /usr/bin/md5sum", "call_md5sum"); }
@@ -191,7 +193,7 @@ sub call_md5sum
sub get_md5sum
{
- ($md5sumoutput) = @_;
+ my ($md5sumoutput) = @_;
my $md5sum;
@@ -357,7 +359,7 @@ sub create_tar_gz_file_from_package
}
$alldirs = installer::systemactions::get_all_directories($installdir);
- $packagename = ${$alldirs}[0]; # only taking the first Solaris package
+ my $packagename = ${$alldirs}[0]; # only taking the first Solaris package
if ( $packagename eq "" ) { installer::exiter::exit_program("ERROR: Could not find package in directory $installdir!", "determine_packagename"); }
installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$packagename);
@@ -368,8 +370,8 @@ sub create_tar_gz_file_from_package
my $ldpreloadstring = "";
if ( $getuidlibrary ne "" ) { $ldpreloadstring = "LD_PRELOAD=" . $getuidlibrary; }
- $systemcall = "cd $installdir; $ldpreloadstring tar -cf - $packagename | gzip > $targzname";
- print "... $systemcall ...\n";
+ my $systemcall = "cd $installdir; $ldpreloadstring tar -cf - $packagename | gzip > $targzname";
+ $installer::logger::Info->printf("... %s ...\n", $systemcall);
my $returnvalue = system($systemcall);
@@ -594,15 +596,15 @@ sub get_download_architecture
{
my $arch = "";
- if ( $installer::globals::compiler =~ /unxlngi/ )
+ if(( $installer::globals::compiler =~ /^unxlngi/ )
+ || ( $installer::globals::compiler =~ /^unxmac.i/ )
+ || ( $installer::globals::issolarisx86build )
+ || ( $installer::globals::iswindowsbuild ))
{
$arch = "x86";
}
- elsif ( $installer::globals::compiler =~ /unxlngppc/ )
- {
- $arch = "PPC";
- }
- elsif ( $installer::globals::compiler =~ /unxlngx/ )
+ elsif(( $installer::globals::compiler =~ /^unxlngx/ )
+ || ( $installer::globals::compiler =~ /^unxmaccx/ ))
{
$arch = "x86-64";
}
@@ -610,19 +612,8 @@ sub get_download_architecture
{
$arch = "Sparc";
}
- elsif ( $installer::globals::issolarisx86build )
- {
- $arch = "x86";
- }
- elsif ( $installer::globals::iswindowsbuild )
- {
- $arch = "x86";
- }
- elsif ( $installer::globals::compiler =~ /^unxmacxi/ )
- {
- $arch = "x86";
- }
- elsif ( $installer::globals::compiler =~ /^unxmacxp/ )
+ elsif(( $installer::globals::compiler =~ /^unxmacxp/ )
+ || ( $installer::globals::compiler =~ /^unxlngppc/ ))
{
$arch = "PPC";
}
@@ -810,7 +801,7 @@ sub create_tar_gz_file_from_directory
$installer::globals::downloadfilename = $downloadfilename . $installer::globals::downloadfileextension;
my $targzname = $downloaddir . $installer::globals::separator . $installer::globals::downloadfilename;
- $systemcall = "cd $changedir; $ldpreloadstring tar -cf - $packdir | gzip > $targzname";
+ my $systemcall = "cd $changedir; $ldpreloadstring tar -cf - $packdir | gzip > $targzname";
my $returnvalue = system($systemcall);
@@ -838,16 +829,13 @@ sub resolve_variables_in_downloadname
# Typical name: soa-{productversion}-{extension}-bin-{os}-{languages}
- my $productversion = "";
- if ( $allvariables->{'PRODUCTVERSION'} ) { $productversion = $allvariables->{'PRODUCTVERSION'}; }
+ my $productversion = $allvariables->{'PRODUCTVERSION'} // "";
$downloadname =~ s/\{productversion\}/$productversion/;
- my $ppackageversion = "";
- if ( $allvariables->{'PACKAGEVERSION'} ) { $packageversion = $allvariables->{'PACKAGEVERSION'}; }
+ my $packageversion = $allvariables->{'PACKAGEVERSION'} // "";
$downloadname =~ s/\{packageversion\}/$packageversion/;
- my $extension = "";
- if ( $allvariables->{'SHORT_PRODUCTEXTENSION'} ) { $extension = $allvariables->{'SHORT_PRODUCTEXTENSION'}; }
+ my $extension = $allvariables->{'SHORT_PRODUCTEXTENSION'} // "";
$extension = lc($extension);
$downloadname =~ s/\{extension\}/$extension/;
@@ -856,8 +844,9 @@ sub resolve_variables_in_downloadname
elsif ( $installer::globals::issolarissparcbuild ) { $os = "solsparc"; }
elsif ( $installer::globals::issolarisx86build ) { $os = "solia"; }
elsif ( $installer::globals::islinuxbuild ) { $os = "linux"; }
- elsif ( $installer::globals::compiler =~ /unxmacxi/ ) { $os = "macosxi"; }
- elsif ( $installer::globals::compiler =~ /unxmacxp/ ) { $os = "macosxp"; }
+ elsif ( $installer::globals::compiler =~ /unxmac.i/ ) { $os = "macosi"; }
+ elsif ( $installer::globals::compiler =~ /unxmac.x/ ) { $os = "macosx"; }
+ elsif ( $installer::globals::compiler =~ /unxmacxp/ ) { $os = "macosp"; }
else { $os = ""; }
$downloadname =~ s/\{os\}/$os/;
@@ -1056,11 +1045,11 @@ sub put_setup_ico_into_template
# Windows: Including the publisher into nsi template
##################################################################
-sub put_publisher_into_template
+sub put_publisher_into_template ($$)
{
- my ($templatefile) = @_;
+ my ($templatefile, $variables) = @_;
- my $publisher = "Sun Microsystems, Inc.";
+ my $publisher = $variables->{'OOOVENDOR'} // "";
replace_one_variable($templatefile, "PUBLISHERPLACEHOLDER", $publisher);
}
@@ -1069,11 +1058,11 @@ sub put_publisher_into_template
# Windows: Including the web site into nsi template
##################################################################
-sub put_website_into_template
+sub put_website_into_template ($$)
{
- my ($templatefile) = @_;
+ my ($templatefile, $variables) = @_;
- my $website = "http\:\/\/www\.openoffice\.org";
+ my $website = $variables->{'STARTCENTER_INFO_URL'} // "";
replace_one_variable($templatefile, "WEBSITEPLACEHOLDER", $website);
}
@@ -1516,7 +1505,8 @@ sub convert_utf16_to_utf8
# open( IN, "<:utf16", $filename ) || installer::exiter::exit_program("ERROR: Cannot open file $filename for reading", "convert_utf16_to_utf8");
# open( IN, "<:para:crlf:uni", $filename ) || installer::exiter::exit_program("ERROR: Cannot open file $filename for reading", "convert_utf16_to_utf8");
open( IN, "<:encoding(UTF16-LE)", $filename ) || installer::exiter::exit_program("ERROR: Cannot open file $filename for reading", "convert_utf16_to_utf8");
- while ( $line = <IN> ) {
+ while ( my $line = <IN> )
+ {
push @localfile, $line;
}
close( IN );
@@ -1545,7 +1535,8 @@ sub convert_utf8_to_utf16
installer::systemactions::copy_one_file($filename, $savfilename);
open( IN, "<:utf8", $filename ) || installer::exiter::exit_program("ERROR: Cannot open file $filename for reading", "convert_utf8_to_utf16");
- while ( $line = <IN> ) {
+ while (my $line = <IN>)
+ {
push @localfile, $line;
}
close( IN );
@@ -1711,27 +1702,36 @@ sub get_path_to_nsis_sdk
my $file;
my $nsispath = "";
- if ( $ENV{'NSIS_PATH'} ) {
+ if ( $ENV{'NSIS_PATH'} )
+ {
$nsispath = $ENV{'NSIS_PATH'};
- } elsif ( $ENV{'SOLARROOT'} ) {
+ }
+ elsif ( $ENV{'SOLARROOT'} )
+ {
$nsispath = $ENV{'SOLARROOT'} . $installer::globals::separator . "NSIS";
- } else {
+ }
+ else
+ {
# do we have nsis already in path ?
- @paths = split(/:/, $ENV{'PATH'});
- foreach $paths (@paths) {
- $paths =~ s/[\/\\]+$//; # remove trailing slashes;
- $nsispath = $paths . "/nsis";
+ my @paths = split(/:/, $ENV{'PATH'});
+ foreach my $path (@paths)
+ {
+ $path =~ s/[\/\\]+$//; # remove trailing slashes;
+ $nsispath = $path . "/nsis";
- if ( -x $nsispath ) {
- $nsispath = $paths;
+ if ( -x $nsispath )
+ {
+ $nsispath = $path;
last;
}
- else {
+ else
+ {
$nsispath = "";
}
}
}
- if ( $ENV{'NSISSDK_SOURCE'} ) {
+ if ( $ENV{'NSISSDK_SOURCE'} )
+ {
installer::logger::print_warning( "NSISSDK_SOURCE is deprecated. use NSIS_PATH instead.\n" );
$nsispath = $ENV{'NSISSDK_SOURCE'}; # overriding the NSIS SDK with NSISSDK_SOURCE
}
@@ -1817,7 +1817,7 @@ sub replace_variables
{
my ($translationfile, $variableshashref) = @_;
- foreach $key (keys %{$variableshashref})
+ foreach my $key (keys %{$variableshashref})
{
my $value = $variableshashref->{$key};
@@ -2063,8 +2063,8 @@ sub create_download_sets
put_banner_bmp_into_template($templatefile, $includepatharrayref, $allvariableshashref);
put_welcome_bmp_into_template($templatefile, $includepatharrayref, $allvariableshashref);
put_setup_ico_into_template($templatefile, $includepatharrayref, $allvariableshashref);
- put_publisher_into_template($templatefile);
- put_website_into_template($templatefile);
+ put_publisher_into_template($templatefile, $allvariableshashref);
+ put_website_into_template($templatefile, $allvariableshashref);
put_javafilename_into_template($templatefile, $allvariableshashref);
put_windows_productversion_into_template($templatefile, $allvariableshashref);
put_windows_productpath_into_template($templatefile, $allvariableshashref, $languagestringref, $localnsisdir);
Modified: openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/globals.pm
URL: http://svn.apache.org/viewvc/openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/globals.pm?rev=1551937&r1=1551936&r2=1551937&view=diff
==============================================================================
--- openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/globals.pm (original)
+++ openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/globals.pm Wed Dec 18 13:27:09 2013
@@ -31,6 +31,8 @@ BEGIN
{
$prog="make_installer.pl";
+ # WARNING: the following lines are matched verbatim in i18npool/source/isolang/langid.pl
+
@noMSLocaleLangs = (
"br",
"bs",
@@ -153,8 +155,8 @@ BEGIN
$fontsfolder = "FontsFolder";
$fontsfoldername = "Fonts";
$fontsdirparent = "";
- $fontsdirname = "";
$fontsdirhostname = "truetype";
+ $fontsdirname = $fontsdirhostname;
$officefolder = "OfficeFolder";
$officemenufolder = "OfficeMenuFolder";
$startupfolder = "StartupFolder";
@@ -232,7 +234,7 @@ BEGIN
$creating_windows_installer_patch = 0;
$strip = 1;
-
+
$globallogging = 0;
$logfilename = "logfile.log"; # the default logfile name for global errors
# @logfileinfo = ();
@@ -263,7 +265,6 @@ BEGIN
$isopensourceproduct = 1;
$manufacturer = "";
$longmanufacturer = "";
- $sundirname = "Oracle";
$codefilename = "codes.txt";
$componentfilename = "components.txt";
$productcode = "";
@@ -364,7 +365,6 @@ BEGIN
@pcfdiffcomment = ();
@epmdifflist = ();
$desktoplinkexists = 0;
- $sundirexists = 0;
$analyze_spellcheckerlanguage = 0;
%spellcheckerlanguagehash = ();
%spellcheckerfilehash = ();
@@ -392,11 +392,8 @@ BEGIN
$officedirhostname = "";
$basisdirhostname = "";
$uredirhostname = "";
- $sundirhostname = "";
$officedirgid = "";
$basisdirgid = "";
- $uredirgid = "";
- $sundirgid = "";
%sign_extensions = ("dll" => "1", "exe" => "1", "cab" => "1");
%treestyles = ();
@@ -416,8 +413,6 @@ BEGIN
$previous_idt_dir = "";
$updatepack = 0;
$msitranpath = "";
- $insert_file_at_end = 0;
- $newfilesexist = 0;
$usesharepointpath = 0;
%newfilescollector = ();
@@ -446,7 +441,7 @@ BEGIN
@environmentvariables = ( "SOLARVERSION", "GUI", "WORK_STAMP", "OUTPATH", "LOCAL_OUT", "LOCAL_COMMON_OUT" );
@packagelistitems = ("module", "solarispackagename", "packagename", "copyright", "vendor", "description" );
@languagepackfeature =();
- @featurecollector =();
+ %featurecollector =();
$msiassemblyfiles = "";
$nsisfilename = "Nsis";
$macinstallfilename = "macinstall.ulf";
@@ -494,10 +489,6 @@ BEGIN
$isunix = 0;
$iswin = 1;
$archiveformat = ".zip";
- %savedmapping = ();
- %savedrevmapping = ();
- %savedrev83mapping = ();
- %saved83dirmapping = ();
}
elsif ( $plat =~ /os2/i )
{
@@ -544,6 +535,13 @@ BEGIN
# ToDo: Needs to be expanded for additional platforms
+ $is_release = 0; # Is changed in parameter.pm when the -release option is given.
+ $source_version = undef;
+ $target_version = undef;
+ $source_msi = undef;
+
+ # Is set to 1 when target_version is a major version, ie ?.0.0
+ $is_major_release = 0;
}
1;
Modified: openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/languages.pm
URL: http://svn.apache.org/viewvc/openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/languages.pm?rev=1551937&r1=1551936&r2=1551937&view=diff
==============================================================================
--- openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/languages.pm (original)
+++ openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/languages.pm Wed Dec 18 13:27:09 2013
@@ -29,6 +29,10 @@ use installer::exiter;
use installer::globals;
use installer::remover;
use installer::ziplist;
+use Digest::MD5;
+
+use strict;
+
=head2 analyze_languagelist()
@@ -70,6 +74,33 @@ sub analyze_languagelist()
+=head2 get_language_directory_name ($language_string)
+
+ Create a directory name that contains the given set of languages.
+ When $language_string exceeds a certain length then it is shortened.
+
+=cut
+sub get_language_directory_name ($)
+{
+ my ($language_string) = @_;
+
+ if (length($language_string) > $installer::globals::max_lang_length)
+ {
+ my $number_of_languages = ($language_string =~ tr/_//);
+ my $digest = new Digest::MD5();
+ $digest->add($language_string);
+ my $short_digest = substr($digest->hexdigest(), 0, 8);
+ return "lang_" . $number_of_languages . "_id_" . $short_digest;
+ }
+ else
+ {
+ return $language_string;
+ }
+}
+
+
+
+
####################################################
# Reading languages from zip list file
####################################################
@@ -122,28 +153,24 @@ sub all_elements_of_array1_in_array2
#############################################
# All languages defined for one product
#############################################
-
-sub get_all_languages_for_one_product
+
+=head2 get_all_languages_for_one_product($languagestring, $allvariables)
+
+ $languagestring can be one or more language names, separated by ','.
+
+ $installer::globals::ismultilingual is set to 1 when $languagestring contains more than one languages.
+
+=cut
+sub get_all_languages_for_one_product ($$)
{
my ( $languagestring, $allvariables ) = @_;
- my @languagearray = ();
- my $last = $languagestring;
-
- $installer::globals::ismultilingual = 0; # setting the global variable $ismultilingual !
- if ( $languagestring =~ /\,/ ) { $installer::globals::ismultilingual = 1; }
-
- while ( $last =~ /^\s*(.+?)\,(.+)\s*$/) # "$" for minimal matching, comma separated list
- {
- my $first = $1;
- $last = $2;
- installer::remover::remove_leading_and_ending_whitespaces(\$first);
- push(@languagearray, "$first");
- }
+ $installer::globals::ismultilingual = ($languagestring =~ /\,/ ) ? 1 : 0;
- installer::remover::remove_leading_and_ending_whitespaces(\$last);
- push(@languagearray, "$last");
+ my $languages = $languagestring;
+ $languages =~ s/\s+//g;
+ my @languagearray = split(/,/, $languages);
if ( $installer::globals::iswindowsbuild )
{
@@ -381,10 +408,101 @@ sub get_java_language
# $javalanguage =~ s/\-/\_/;
# }
- $javalanguage = $language;
+ my $javalanguage = $language;
$javalanguage =~ s/\-/\_/;
return $javalanguage;
}
+
+
+=head2 get_key_language ($languages)
+
+ Determine the key language from the array of @$languages.
+
+ If there is only one language then that is the key language.
+
+ If there are two languages and one is en-US and was automatically
+ added, then the other language is the key language.
+
+ When there is more than one language and the case above does not
+ apply then return either 'multiasia' or 'multiwestern' as key
+ language, depending on whether one of the asian language parts
+ 'jp', 'ko', 'zh' appear.
+
+=cut
+sub get_key_language ($)
+{
+ my ($languages) = @_;
+
+ my $language_count = scalar @$languages;
+
+ if ($language_count == 1)
+ {
+ return $languages->[0];
+ }
+ else
+ {
+ if ($installer::globals::added_english && $language_count==1)
+ {
+ # Only multilingual because of added English.
+ return $languages->[1];
+ }
+ else
+ {
+ if ($languages->[1] =~ /(jp|ko|zh)/)
+ {
+ return "multiasia";
+ }
+ else
+ {
+ return "multiwestern";
+ }
+ }
+ }
+}
+
+
+
+
+=head2 get_normalized_language ($language)
+
+ Transform "..._<language>" into "<language>".
+ The ... part, if it exists, is typically en-US.
+
+ If $language does not contain a '_' then $language is returned unmodified.
+
+=cut
+sub get_normalized_language ($)
+{
+ my ($language) = @_;
+
+ if (ref($language) eq "ARRAY")
+ {
+ if (scalar @$language > 1)
+ {
+ if ($language->[0] eq "en-US")
+ {
+ return $language->[1];
+ }
+ else
+ {
+ return $language->[0];
+ }
+ }
+ else
+ {
+ return join("_", @$language);
+ }
+ }
+ elsif ($language =~ /^.*?_(.*)$/)
+ {
+ return $1;
+ }
+ else
+ {
+ return $language;
+ }
+}
+
1;
Modified: openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/logger.pm
URL: http://svn.apache.org/viewvc/openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/logger.pm?rev=1551937&r1=1551936&r2=1551937&view=diff
==============================================================================
--- openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/logger.pm (original)
+++ openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/logger.pm Wed Dec 18 13:27:09 2013
@@ -89,6 +89,44 @@ our $Info = installer::logger->new("info
'is_show_log_id' => 0
);
+
+
+=head2 SetupSimpleLogging ($filename)
+
+ Setup logging so that $Global, $Lang and $Info all print to the console.
+ If $filename is given then logging also goes to that file.
+
+=cut
+sub SetupSimpleLogging (;$)
+{
+ my ($log_filename) = @_;
+
+ $Info = installer::logger->new("info",
+ 'is_print_to_console' => 1,
+ 'is_show_relative_time' => 1,
+ );
+ $Global = installer::logger->new("glob",
+ 'is_print_to_console' => 0,
+ 'is_show_relative_time' => 1,
+ 'forward' => [$Info]
+ );
+ $Lang = installer::logger->new("lang",
+ 'is_print_to_console' => 0,
+ 'is_show_relative_time' => 1,
+ 'forward' => [$Info]
+ );
+ if (defined $log_filename)
+ {
+ $Info->set_filename($log_filename);
+ }
+ $Info->{'is_print_to_console'} = 1;
+ $installer::globals::quiet = 0;
+ starttime();
+}
+
+
+
+
=head2 new($class, $id, @arguments)
Create a new instance of the logger class.
@@ -119,7 +157,9 @@ sub new ($$@)
# Show log id (mostly for debugging the logger)
'is_show_log_id' => 0,
# Show the process id, useful on the console when doing a multiprocessor build.
- 'is_show_process_id' => 0
+ 'is_show_process_id' => 0,
+ # Current indentation
+ 'indentation' => "",
};
while (scalar @arguments >= 2)
{
@@ -219,6 +259,7 @@ sub process_line ($$$$$$)
{
$line .= $pid . " : ";
}
+ $line .= $self->{'indentation'};
$line .= $message;
# Print the line to a file or to the console or store it for later use.
@@ -359,6 +400,24 @@ sub set_forward ($$)
+sub increase_indentation ($)
+{
+ my ($self) = @_;
+ $self->{'indentation'} .= " ";
+}
+
+
+
+
+sub decrease_indentation ($)
+{
+ my ($self) = @_;
+ $self->{'indentation'} = substr($self->{'indentation'}, 4);
+}
+
+
+
+
####################################################
# Including header files into the logfile
####################################################
@@ -637,6 +696,9 @@ sub print_error
{
my $message = shift;
chomp $message;
+
+ PrintError($message);
+
print STDERR "\n";
print STDERR "**************************************************\n";
print STDERR "ERROR: $message";
@@ -646,6 +708,18 @@ sub print_error
}
+
+
+sub PrintError ($@)
+{
+ my ($format, @arguments) = @_;
+
+ $Info->printf("Error: ".$format, @arguments);
+}
+
+
+
+
=head2 PrintStackTrace()
This is for debugging the print and printf methods of the logger class and their use.
Therefore we use the Perl print/printf directly and not the logger methods to avoid loops in case of errors.
Modified: openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/packagepool.pm
URL: http://svn.apache.org/viewvc/openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/packagepool.pm?rev=1551937&r1=1551936&r2=1551937&view=diff
==============================================================================
--- openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/packagepool.pm (original)
+++ openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/packagepool.pm Wed Dec 18 13:27:09 2013
@@ -163,16 +163,15 @@ sub compare_package_content
if ( $identical )
{
my $first = 1;
- my $start = "\n";
foreach my $dest ( keys %{$newcontent} )
{
if ( ! exists($oldcontent->{$dest}) )
{
$identical = 0;
- $installer::logger::Info->printf("%s...... file only in one package (A): %s\n", $start, $dest);
+ $installer::logger::Info->print("\n") if $first;
+ $installer::logger::Info->printf("...... file only in one package (A): %s\n", $dest);
$infoline = "File only in existing pool package: $dest\n";
push(@installer::globals::pcfdiffcomment, $infoline);
- if ( $first ) { $start = ""; }
$first = 0;
}
}
@@ -185,10 +184,10 @@ sub compare_package_content
if ( ! exists($newcontent->{$dest}) )
{
$identical = 0;
- $installer::logger::Info->printf("%s...... file only in one package (B): %s\n", $start, $dest);
+ $installer::logger::Info->print("\n") if $first;
+ $installer::logger::Info->printf("...... file only in one package (B): %s\n", $dest);
$infoline = "File only in new package: $dest\n";
push(@installer::globals::pcfdiffcomment, $infoline);
- if ( $first ) { $start = ""; }
$first = 0;
}
}
Modified: openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/parameter.pm
URL: http://svn.apache.org/viewvc/openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/parameter.pm?rev=1551937&r1=1551936&r2=1551937&view=diff
==============================================================================
--- openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/parameter.pm (original)
+++ openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/parameter.pm Wed Dec 18 13:27:09 2013
@@ -164,6 +164,10 @@ sub getparameter
$path =~ s/^\Q$installer::globals::destdir\E//;
$installer::globals::rootpath = $path;
}
+ elsif ($param eq "-release")
+ {
+ $installer::globals::is_release = 1;
+ }
else
{
installer::logger::print_error( "unknown parameter: $param" );
@@ -171,7 +175,7 @@ sub getparameter
exit(-1);
}
}
-
+
# Usage of simple installer (not for Windows):
# $PERL -w $SOLARENV/bin/make_installer.pl \
# -f openoffice.lst -l en-US -p OpenOffice \
@@ -634,7 +638,6 @@ sub outputparameter ()
foreach my $line (@output)
{
$installer::logger::Info->print($line);
- $installer::logger::Global->print($line);
}
}
Modified: openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/patch/FileSequenceList.pm
URL: http://svn.apache.org/viewvc/openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/patch/FileSequenceList.pm?rev=1551937&r1=1551936&r2=1551937&view=diff
==============================================================================
--- openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/patch/FileSequenceList.pm (original)
+++ openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/patch/FileSequenceList.pm Wed Dec 18 13:27:09 2013
@@ -1,159 +1,156 @@
-#**************************************************************
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-#**************************************************************
-
-package installer::patch::FileSequenceList;
-
-use XML::LibXML;
-use strict;
-
-=head1 NAME
-
- FileSequenceList.pm - Class for retrieving and processing the 'Sequence' values of the MSI 'File' table.
-
-=cut
-
-=head2 new($class)
-
- Create a new FileSequenceList object.
-
-=cut
-sub new ($)
-{
- my ($class) = @_;
-
- my $self = {
- 'data' => undef
- };
- bless($self, $class);
-
- return $self;
-}
-
-
-
-
-sub SetFromFileList ($$)
-{
- my ($self, $files) = @_;
-
- my %data = map {$_->{'uniquename'} => $_->{'sequencenumber'}} @$files;
- $self->{'data'} = \%data;
-}
-
-
-
-
-sub SetFromMap ($$)
-{
- my ($self, $map) = @_;
-
- $self->{'data'} = $map;
-}
-
-
-
-
-sub GetFileCount ($)
-{
- my ($self) = @_;
-
- return scalar keys %{$self->{'data'}};
-}
-
-
-
-
-=head2 GetSequenceNumbers ($files)
-
- $files is a hash that maps unique file names (File->File) to sequence
- numbers (File->Sequence). The later is (expected to be) initially unset and
- is set in this method.
-
- For new files -- entries in the given $files that do not exist in the 'data'
- member -- no sequence numbers are defined.
-
- When there are removed files -- entries in the 'data' member that do not
- exist in the given $files -- then a list of these files is returned. In
- that case the given $files remain unmodified.
-
- The returned list is empty when everyting is OK.
-
-=cut
-sub GetSequenceNumbers ($$)
-{
- my ($self, $files) = @_;
-
- # Check if files have been removed.
- my @missing = ();
- foreach my $name (keys %{$self->{'data'}})
- {
- if ( ! defined $files->{$name})
- {
- push @missing, $name;
- }
- }
- if (scalar @missing > 0)
- {
- # Yes. Return the names of the removed files.
- return @missing;
- }
-
- # No files where removed. Set the sequence numbers.
- foreach my $name (keys %$files)
- {
- $files->{$name} = $self->{'data'}->{$name};
- }
- return ();
-}
-
-
-
-
-sub GetDifference ($$)
-{
- my ($self, $other) = @_;
-
- # Create maps for easy reference.
- my (@files_in_both, @files_in_self, @files_in_other);
- foreach my $name (keys %{$self->{'data'}})
- {
- if (defined $other->{'data'}->{$name})
- {
- push @files_in_both, $name;
- }
- else
- {
- push @files_in_self, $name;
- }
- }
- foreach my $name (keys %{$self->{'data'}})
- {
- if ( ! defined $self->{'data'}->{$name})
- {
- push @files_in_other, $name;
- }
- }
-
- return (\@files_in_both, \@files_in_self, \@files_in_other);
-}
-
-
-1;
+#**************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+#**************************************************************
+
+package installer::patch::FileSequenceList;
+
+use strict;
+
+=head1 NAME
+
+ FileSequenceList.pm - Class for retrieving and processing the 'Sequence' values of the MSI 'File' table.
+
+=cut
+
+=head2 new($class)
+
+ Create a new FileSequenceList object.
+
+=cut
+sub new ($)
+{
+ my ($class) = @_;
+
+ my $self = {
+ 'data' => undef
+ };
+ bless($self, $class);
+
+ return $self;
+}
+
+
+
+
+sub SetFromMap ($$)
+{
+ my ($self, $map) = @_;
+
+ $self->{'data'} = $map;
+}
+
+
+
+
+sub SetFromMsi ($$)
+{
+ my ($self, $msi) = @_;
+
+ my $file_table = $msi->GetTable("File");
+ my $file_map = $msi->GetFileMap();
+
+ my $file_column_index = $file_table->GetColumnIndex("File");
+ my $filename_column_index = $file_table->GetColumnIndex("FileName");
+ my $sequence_column_index = $file_table->GetColumnIndex("Sequence");
+
+ my %sequence_data = ();
+
+ printf("extracting columns %d and %d from %d rows\n",
+ $file_column_index,
+ $sequence_column_index,
+ $file_table->GetRowCount());
+
+ foreach my $row (@{$file_table->GetAllRows()})
+ {
+ my $unique_name = $row->GetValue($file_column_index);
+ my $filename = $row->GetValue($filename_column_index);
+ my ($long_filename,$short_filename) = installer::patch::Msi::SplitLongShortName($filename);
+ my $sequence = $row->GetValue($sequence_column_index);
+ my $directory_item = $file_map->{$unique_name}->{'directory'};
+ my $source_path = $directory_item->{'full_source_long_name'};
+ my $target_path = $directory_item->{'full_target_long_name'};
+ my $key = $source_path ne ""
+ ? $source_path."/".$long_filename
+ : $long_filename;
+ $sequence_data{$key} = {
+ 'sequence' => $sequence,
+ 'uniquename' => $unique_name,
+ 'row' => $row
+ };
+ }
+ $self->{'data'} = \%sequence_data;
+}
+
+
+
+
+sub GetFileCount ($)
+{
+ my ($self) = @_;
+
+ return scalar keys %{$self->{'data'}};
+}
+
+
+
+
+sub get_removed_files ($@)
+{
+ my ($self, $target_unique_names) = @_;
+
+ my %uniquename_to_row_map = map{$_->{'uniquename'} => $_->{'row'}} values %{$self->{'data'}};
+
+ # Check if files have been removed.
+ my @missing = ();
+ foreach my $item (values %{$self->{'data'}})
+ {
+ my ($uniquename, $row) = ($item->{'uniquename'}, $item->{'row'});
+ if ( ! defined $target_unique_names->{$uniquename})
+ {
+ # $name is defined in source but not in target => it has been removed.
+ push @missing, $row;
+ }
+ }
+ return @missing;
+}
+
+
+
+
+sub get_sequence_and_unique_name($$)
+{
+ my ($self, $source_path) = @_;
+
+ my $sequence_and_unique_name = $self->{'data'}->{$source_path};
+ if ( ! defined $sequence_and_unique_name)
+ {
+ $installer::logger::Lang->printf("can not find entry for source path '%s'\n", $source_path);
+ return (undef,undef);
+ }
+ else
+ {
+ return (
+ $sequence_and_unique_name->{'sequence'},
+ $sequence_and_unique_name->{'uniquename'});
+ }
+}
+
+
+1;
Modified: openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/patch/InstallationSet.pm
URL: http://svn.apache.org/viewvc/openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/patch/InstallationSet.pm?rev=1551937&r1=1551936&r2=1551937&view=diff
==============================================================================
--- openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/patch/InstallationSet.pm (original)
+++ openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/patch/InstallationSet.pm Wed Dec 18 13:27:09 2013
@@ -1,467 +1,854 @@
-#**************************************************************
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-#**************************************************************
-
-package installer::patch::InstallationSet;
-
-use installer::patch::Tools;
-use installer::patch::Version;
-use installer::logger;
-
-
-my $Unpacker = "/c/Program\\ Files/7-Zip/7z.exe";
-
-=head1 NAME
-
- package installer::patch::InstallationSet - Functions for handling installation sets
-
-=head1 DESCRIPTION
-
- This package contains functions for unpacking the .exe files that
- are created by the NSIS installer creator and the .cab files in
- the installation sets.
-
-=cut
-
-sub UnpackExe ($$)
-{
- my ($filename, $destination_path) = @_;
-
- $installer::logger::Info->printf("unpacking installation set to '%s'\n", $destination_path);
-
- # Unpack to a temporary path and change its name to the destination path
- # only when the unpacking has completed successfully.
- my $temporary_destination_path = $destination_path . ".tmp";
- File::Path::make_path($temporary_destination_path);
-
- my $windows_filename = installer::patch::Tools::CygpathToWindows($filename);
- my $windows_destination_path = installer::patch::Tools::CygpathToWindows($temporary_destination_path);
- my $command = join(" ",
- $Unpacker,
- "x", "-o".$windows_destination_path,
- $windows_filename);
- my $result = qx($command);
-
- # Check the existence of the .cab files.
- my $cab_filename = File::Spec->catfile($temporary_destination_path, "openoffice1.cab");
- if ( ! -f $cab_filename)
- {
- installer::logger::PrintError("cab file '%s' was not extracted from installation set\n", $cab_filename);
- return 0;
- }
- if (rename($temporary_destination_path, $destination_path) == 0)
- {
- installer::logger::PrintError("can not rename temporary extraction directory\n");
- return 0;
- }
- return 1;
-}
-
-
-
-
-=head2 UnpackCab($cab_filename, $destination_path)
-
- Unpacking the cabinet file inside an .exe installation set is a
- three step process because there is no directory information stored
- inside the cab file. This has to be taken from the 'File' and
- 'Directory' tables in the .msi file.
-
- 1. Setup the directory structure of all files in the cab from the 'File' and 'Directory' tables in the msi.
-
- 2. Unpack the cab file.
-
- 3. Move the files to their destination directories.
-
-=cut
-sub UnpackCab ($$$)
-{
- my ($cab_filename, $msi, $destination_path) = @_;
-
- # Step 1
- # Extract the directory structure from the 'File' and 'Directory' tables in the given msi.
- $installer::logger::Info->printf("setting up directory tree\n");
- my $file_table = $msi->GetTable("File");
- my $file_to_directory_map = $msi->GetFileToDirectoryMap();
-
- # Step 2
- # Unpack the .cab file to a temporary path.
- my $temporary_destination_path = $destination_path . ".tmp";
- if ( -d $temporary_destination_path)
- {
- # Temporary directory already exists => cab file has already been unpacked (flat), nothing to do.
- $installer::logger::Info->printf("cab file has already been unpacked to flat structure\n");
- }
- else
- {
- UnpackCabFlat($cab_filename, $temporary_destination_path, $file_table);
- }
-
- # Step 3
- # Move the files to their destinations.
- File::Path::make_path($destination_path);
- $installer::logger::Info->printf("moving files to their directories\n");
- my $count = 0;
- foreach my $file_row (@{$file_table->GetAllRows()})
- {
- my $unique_name = $file_row->GetValue('File');
- my $directory_full_names = $file_to_directory_map->{$unique_name};
- my ($source_full_name, $target_full_name) = @$directory_full_names;
-
- my $flat_filename = File::Spec->catfile($temporary_destination_path, $unique_name);
- my $dir_path = File::Spec->catfile($destination_path, $source_full_name);
- my $dir_filename = File::Spec->catfile($dir_path, $unique_name);
-
- printf("%d: making path %s and copying %s to %s\n",
- $count,
- $dir_path,
- $unique_name,
- $dir_filename);
- File::Path::make_path($dir_path);
- File::Copy::move($flat_filename, $dir_filename);
-
- ++$count;
- }
-
- # Cleanup. Remove the temporary directory. It should be empty by now.
- rmdir($temporary_destination_path);
-}
-
-
-
-
-=head2 UnpackCabFlat ($cab_filename, $destination_path, $file_table)
-
- Unpack the flat file structure of the $cab_filename to $destination_path.
-
- In order to detect and handle an incomplete (arborted) previous
- extraction, the cab file is unpacked to a temprorary directory
- that after successful extraction is renamed to $destination_path.
-
-=cut
-sub UnpackCabFlat ($$$)
-{
- my ($cab_filename, $destination_path, $file_table) = @_;
-
- # Unpack the .cab file to a temporary path (note that
- # $destination_path may alreay bee a temporary path). Using a
- # second one prevents the lengthy flat unpacking to be repeated
- # when another step fails.
-
- $installer::logger::Info->printf("unpacking cab file\n");
- my $temporary_destination_path = $destination_path . ".tmp";
- File::Path::make_path($temporary_destination_path);
- my $windows_cab_filename = installer::patch::Tools::CygpathToWindows($cab_filename);
- my $windows_destination_path = installer::patch::Tools::CygpathToWindows($temporary_destination_path);
- my $command = join(" ",
- $Unpacker,
- "x", "-o".$windows_destination_path,
- $windows_cab_filename,
- "-y");
- printf("running command '%s'\n", $command);
- open my $cmd, $command."|";
- my $extraction_count = 0;
- my $file_count = $file_table->GetRowCount();
- while (<$cmd>)
- {
- my $message = $_;
- chomp($message);
- ++$extraction_count;
- printf("%4d/%4d %3.2f%% \r",
- $extraction_count,
- $file_count,
- $extraction_count*100/$file_count);
- }
- close $cmd;
- printf("extraction done \n");
-
- rename($temporary_destination_path, $destination_path)
- || installer::logger::PrintError(
- "can not rename the temporary directory '%s' to '%s'\n",
- $temporary_destination_path,
- $destination_path);
-}
-
-
-
-
-=head GetUnpackedMsiPath ($version, $language, $package_format, $product)
-
- Convenience function that returns where a downloadable installation set is extracted to.
-
-=cut
-sub GetUnpackedMsiPath ($$$$)
-{
- my ($version, $language, $package_format, $product) = @_;
-
- return File::Spec->catfile(
- GetUnpackedPath($version, $language, $package_format, $product),
- "unpacked_msi");
-}
-
-
-
-
-=head GetUnpackedCabPath ($version, $language, $package_format, $product)
-
- Convenience function that returns where a cab file is extracted
- (with injected directory structure from the msi file) to.
-
-=cut
-sub GetUnpackedCabPath ($$$$)
-{
- my ($version, $language, $package_format, $product) = @_;
-
- return File::Spec->catfile(
- GetUnpackedPath($version, $language, $package_format, $product),
- "unpacked_cab");
-}
-
-
-
-
-=head2 GetUnpackedPath($version, $language, $package_format, $product)
-
- Internal function for creating paths to where archives are unpacked.
-
-=cut
-sub GetUnpackedPath ($$$$)
-{
- my ($version, $language, $package_format, $product) = @_;
-
- return File::Spec->catfile(
- $ENV{'SRC_ROOT'},
- "instsetoo_native",
- $ENV{'INPATH'},
- $product,
- $package_format,
- installer::patch::Version::ArrayToDirectoryName(installer::patch::Version::StringToNumberArray($version)),
- $language);
-}
-
-
-
-
-=head2 Download($language, $release_data, $filename)
-
- Download an installation set to $filename. The URL for the
- download is taken from $release_data, a snippet from the
- instsetoo_native/data/releases.xml file.
-
-=cut
-sub Download ($$$)
-{
- my ($language, $release_data, $filename) = @_;
-
- my $url = $release_data->{'URL'};
- $release_data->{'URL'} =~ /^(.*)\/([^\/]+)$/;
- my ($location, $basename) = ($1,$2);
-
- $installer::logger::Info->printf("downloading %s\n", $basename);
- $installer::logger::Info->printf(" from '%s'\n", $location);
- my $filesize = $release_data->{'file-size'};
- $installer::logger::Info->printf(" expected size is %d\n", $filesize);
- my $temporary_filename = $filename . ".part";
- my $resume_size = 0;
- if ( -f $temporary_filename)
- {
- $resume_size = -s $temporary_filename;
- $installer::logger::Info->printf(" trying to resume at %d/%d bytes\n", $resume_size, $filesize);
- }
-
- # Prepare checksum.
- my $checksum = undef;
- my $checksum_type = $release_data->{'checksum-type'};
- my $checksum_value = $release_data->{'checksum-value'};
- my $digest = undef;
- if ($checksum_type eq "sha256")
- {
- $digest = Digest->new("SHA-256");
- }
- elsif ($checksum_type eq "md5")
- {
- $digest = Digest->new("md5");
- }
- else
- {
- installer::logger::PrintError(
- "checksum type %s is not supported. Supported checksum types are: sha256,md5\n",
- $checksum_type);
- return 0;
- }
-
- # Download the extension.
- open my $out, ">>$temporary_filename";
- binmode($out);
-
- my $mode = $|;
- my $handle = select STDOUT;
- $| = 1;
- select $handle;
-
- my $agent = LWP::UserAgent->new();
- $agent->timeout(120);
- $agent->show_progress(0);
- my $last_was_redirect = 0;
- my $bytes_read = 0;
- $agent->add_handler('response_redirect'
- => sub{
- $last_was_redirect = 1;
- return;
- });
- $agent->add_handler('response_data'
- => sub{
- if ($last_was_redirect)
- {
- $last_was_redirect = 0;
- # Throw away the data we got so far.
- $digest->reset();
- close $out;
- open $out, ">$temporary_filename";
- binmode($out);
- }
- my($response,$agent,$h,$data)=@_;
- print $out $data;
- $digest->add($data);
- $bytes_read += length($data);
- printf("read %*d / %d %d%% \r",
- length($filesize),
- $bytes_read,
- $filesize,
- $bytes_read*100/$filesize);
- });
- my $response;
- if ($resume_size > 0)
- {
- $response = $agent->get($url, 'Range' => "bytes=$resume_size-");
- }
- else
- {
- $response = $agent->get($url);
- }
- close $out;
-
- $handle = select STDOUT;
- $| = $mode;
- select $handle;
-
- $installer::logger::Info->print(" \r");
-
- if ($response->is_success())
- {
- if ($digest->hexdigest() eq $checksum_value)
- {
- $installer::logger::Info->PrintInfo("download was successfull\n");
- if ( ! rename($temporary_filename, $filename))
- {
- installer::logger::PrintError("can not rename '%s' to '%s'\n", $temporary_filename, $filename);
- return 0;
- }
- else
- {
- return 1;
- }
- }
- else
- {
- installer::logger::PrintError("%s checksum is wrong\n", $checksum_type);
- return 0;
- }
- }
- else
- {
- installer::logger::PrintError("there was a download error\n");
- return 0;
- }
-}
-
-
-
-
-=head2 ProvideDownloadSet ($version, $language, $package_format)
-
- Download an installation set when it is not yet present to
- $ENV{'TARFILE_LOCATION'}. Verify the downloaded file with the
- checksum that is extracted from the
- instsetoo_native/data/releases.xml file.
-
-=cut
-sub ProvideDownloadSet ($$$)
-{
- my ($version, $language, $package_format) = @_;
-
- my $release_item = installer::patch::ReleasesList::Instance()->{$version}->{$package_format}->{$language};
-
- # Get basename of installation set from URL.
- $release_item->{'URL'} =~ /^(.*)\/([^\/]+)$/;
- my ($location, $basename) = ($1,$2);
-
- # Is the installation set already present in ext_sources/ ?
- my $need_download = 0;
- my $ext_sources_filename = File::Spec->catfile(
- $ENV{'TARFILE_LOCATION'},
- $basename);
- if ( ! -f $ext_sources_filename)
- {
- $installer::logger::Info->printf("download set is not in ext_sources/ (%s)\n", $ext_sources_filename);
- $need_download = 1;
- }
- else
- {
- $installer::logger::Info->printf("download set exists at '%s'\n", $ext_sources_filename);
- if ($release_item->{'checksum-type'} eq 'sha256')
- {
- $installer::logger::Info->printf("checking SHA256 checksum\n");
- my $digest = Digest->new("SHA-256");
- open my $in, "<", $ext_sources_filename;
- $digest->addfile($in);
- close $in;
- if ($digest->hexdigest() ne $release_item->{'checksum-value'})
- {
- $installer::logger::Info->printf(" mismatch\n", $ext_sources_filename);
- $need_download = 1;
- }
- else
- {
- $installer::logger::Info->printf(" match\n");
- }
- }
- }
-
- if ($need_download)
- {
- if ( ! installer::patch::InstallationSet::Download(
- $language,
- $release_item,
- $ext_sources_filename))
- {
- return 0;
- }
- if ( ! -f $ext_sources_filename)
- {
- $installer::logger::Info->printf("download set could not be downloaded\n");
- return 0;
- }
- }
-
- return $ext_sources_filename;
-}
-
-1;
+#**************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+#**************************************************************
+
+package installer::patch::InstallationSet;
+
+use installer::patch::Tools;
+use installer::patch::Version;
+use installer::logger;
+
+use strict;
+
+# Call Get7Zip() to get access to the filename of the 7z executable.
+my $SevenZip = undef;
+
+
+=head1 NAME
+
+ package installer::patch::InstallationSet - Functions for handling installation sets
+
+=head1 DESCRIPTION
+
+ This package contains functions for unpacking the .exe files that
+ are created by the NSIS installer creator and the .cab files in
+ the installation sets.
+
+=cut
+
+
+
+
+=head2 Detect7ZipOnWindows ()
+
+ 7Zip seems to be the only program able to unpack an NSIS installer.
+ Search for it.
+
+=cut
+
+sub Detect7ZipOnWindows ()
+{
+ # Use 'reg query' to read registry entry from Windows registry.
+ my $registry_key = "HKEY_CURRENT_USER\\\\Software\\\\7-Zip";
+ my $registry_value_name = "Path";
+ my $command = sprintf("reg query %s /v %s", $registry_key, $registry_value_name);
+ my $response = qx($command);
+
+ # Process the response.
+ my $path_to_7zip = undef;
+ if ($response =~ /\s+REG_SZ\s+([^\r\n]*)/m)
+ {
+ $path_to_7zip = $1;
+ }
+
+ # If that failed, then make an educated guess.
+ if ( ! defined $path_to_7zip)
+ {
+ $path_to_7zip = "c:\\Program Files\\7-Zip\\";
+ }
+
+ # Check if the executable exists and is, well, executable.
+ return undef unless -d $path_to_7zip;
+ my $fullname = File::Spec->catfile($path_to_7zip, "7z.exe");
+ return undef unless -f $fullname;
+ return undef unless -x $fullname;
+
+ return $fullname;
+}
+
+
+
+
+sub Get7Zip ()
+{
+ if ( ! defined $SevenZip)
+ {
+ if ($ENV{'OS'} eq "WNT")
+ {
+ $SevenZip = Detect7ZipOnWindows();
+ }
+ if ( ! defined $SevenZip)
+ {
+ # Use an empty string to avoid repeated (and failing) detections of a missing 7z.
+ $SevenZip = "";
+ }
+ }
+
+ return $SevenZip eq "" ? undef : $SevenZip;
+}
+
+
+
+
+sub UnpackExe ($$)
+{
+ my ($filename, $destination_path) = @_;
+
+ $installer::logger::Info->printf("unpacking installation set to '%s'\n", $destination_path);
+
+ # Unpack to a temporary path and change its name to the destination path
+ # only when the unpacking has completed successfully.
+ File::Path::make_path($destination_path);
+
+ my $windows_filename = installer::patch::Tools::ToEscapedWindowsPath($filename);
+ my $windows_destination_path = installer::patch::Tools::ToEscapedWindowsPath($destination_path);
+ my $command = join(" ",
+ "\"".Get7Zip()."\"",
+ "x",
+ "-y",
+ "-o".$windows_destination_path,
+ $windows_filename);
+ my $result = qx($command);
+ if ( ! $result)
+ {
+ installer::exiter::exit_program(
+ "ERROR: can not unpack downloadable installation set: ".$!,
+ "installer::patch::InstallationSet::UnpackExe");
+ }
+
+ # Check the existence of the .cab files.
+ my $cab_filename = File::Spec->catfile($destination_path, "openoffice1.cab");
+ if ( ! -f $cab_filename)
+ {
+ installer::logger::PrintError("cab file '%s' was not extracted from installation set\n", $cab_filename);
+ return 0;
+ }
+ return 1;
+}
+
+
+
+
+=head2 UnpackCab($cab_filename, $destination_path)
+
+ Unpacking the cabinet file inside an .exe installation set is a
+ three step process because there is no directory information stored
+ inside the cab file. This has to be taken from the 'File' and
+ 'Directory' tables in the .msi file.
+
+ 1. Setup the directory structure of all files in the cab from the 'File' and 'Directory' tables in the msi.
+
+ 2. Unpack the cab file.
+
+ 3. Move the files to their destination directories.
+
+=cut
+sub UnpackCab ($$$)
+{
+ my ($cab_filename, $msi, $destination_path) = @_;
+
+ # Step 1
+ # Extract the directory structure from the 'File' and 'Directory' tables in the given msi.
+ $installer::logger::Info->printf("setting up directory tree\n");
+ my $file_table = $msi->GetTable("File");
+ my $file_map = $msi->GetFileMap();
+
+ # Step 2
+ # Unpack the .cab file to a temporary path.
+ my $temporary_destination_path = $destination_path . ".tmp";
+ if ( -d $temporary_destination_path)
+ {
+ # Temporary directory already exists => cab file has already been unpacked (flat), nothing to do.
+ printf("%s exists\n", $temporary_destination_path);
+ $installer::logger::Info->printf("cab file has already been unpacked to flat structure\n");
+ }
+ else
+ {
+ UnpackCabFlat($cab_filename, $temporary_destination_path, $file_table);
+ }
+
+ # Step 3
+ # Move the files to their destinations.
+ File::Path::make_path($destination_path);
+ $installer::logger::Info->printf("moving files to their directories\n");
+ my $directory_map = $msi->GetDirectoryMap();
+ my $office_menu_folder_name = $directory_map->{'INSTALLLOCATION'}->{'target_long_name'};
+ my $count = 0;
+ foreach my $file_row (@{$file_table->GetAllRows()})
+ {
+ my $unique_name = $file_row->GetValue('File');
+ my $file_item = $file_map->{$unique_name};
+ my $directory_item = $file_item->{'directory'};
+ my $long_file_name = $file_item->{'long_name'};
+ my $full_name = $directory_item->{'full_source_long_name'};
+ # Strip away the leading OfficeMenuFolder part.
+ $full_name =~ s/^$office_menu_folder_name\///;
+ my $flat_filename = File::Spec->catfile($temporary_destination_path, $unique_name);
+ my $dir_path = File::Spec->catfile($destination_path, $full_name);
+ my $dir_filename = File::Spec->catfile($dir_path, $long_file_name);
+
+ if ( ! -d $dir_path)
+ {
+ File::Path::make_path($dir_path);
+ }
+
+ $installer::logger::Lang->printf("moving %s to %s\n", $flat_filename, $dir_filename);
+ File::Copy::move($flat_filename, $dir_filename)
+ || die("can not move file ".$flat_filename.":".$!);
+
+ ++$count;
+ }
+
+ # Cleanup. Remove the temporary directory. It should be empty by now.
+ rmdir($temporary_destination_path);
+}
+
+
+
+
+=head2 UnpackCabFlat ($cab_filename, $destination_path, $file_table)
+
+ Unpack the flat file structure of the $cab_filename to $destination_path.
+
+ In order to detect and handle an incomplete (arborted) previous
+ extraction, the cab file is unpacked to a temprorary directory
+ that after successful extraction is renamed to $destination_path.
+
+=cut
+sub UnpackCabFlat ($$$)
+{
+ my ($cab_filename, $destination_path, $file_table) = @_;
+
+ # Unpack the .cab file to a temporary path (note that
+ # $destination_path may alreay bee a temporary path). Using a
+ # second one prevents the lengthy flat unpacking to be repeated
+ # when another step fails.
+
+ $installer::logger::Info->printf("unpacking cab file\n");
+ File::Path::make_path($destination_path);
+ my $windows_cab_filename = installer::patch::Tools::ToEscapedWindowsPath($cab_filename);
+ my $windows_destination_path = installer::patch::Tools::ToEscapedWindowsPath($destination_path);
+ my $command = join(" ",
+ "\"".Get7Zip()."\"",
+ "x", "-o".$windows_destination_path,
+ $windows_cab_filename,
+ "-y");
+ open my $cmd, $command."|";
+ my $extraction_count = 0;
+ my $file_count = $file_table->GetRowCount();
+ while (<$cmd>)
+ {
+ my $message = $_;
+ chomp($message);
+ ++$extraction_count;
+ printf("%4d/%4d %3.2f%% \r",
+ $extraction_count,
+ $file_count,
+ $extraction_count*100/$file_count);
+ }
+ close $cmd;
+}
+
+
+
+
+=head GetUnpackedExePath ($version, $is_current_version, $language, $package_format, $product)
+
+ Convenience function that returns where a downloadable installation set is extracted to.
+
+=cut
+sub GetUnpackedExePath ($$$$$)
+{
+ my ($version, $is_current_version, $language, $package_format, $product) = @_;
+
+ my $path = GetUnpackedPath($version, $is_current_version, $language, $package_format, $product);
+ return File::Spec->catfile($path, "unpacked");
+}
+
+
+
+
+=head GetUnpackedCabPath ($version, $is_current_version, $language, $package_format, $product)
+
+ Convenience function that returns where a cab file is extracted
+ (with injected directory structure from the msi file) to.
+
+=cut
+sub GetUnpackedCabPath ($$$$$)
+{
+ my ($version, $is_current_version, $language, $package_format, $product) = @_;
+
+ my $path = GetUnpackedPath($version, $is_current_version, $language, $package_format, $product);
+ return File::Spec->catfile($path, "unpacked");
+}
+
+
+
+
+=head2 GetUnpackedPath($version, $is_current_version, $language, $package_format, $product)
+
+ Internal function for creating paths to where archives are unpacked.
+
+=cut
+sub GetUnpackedPath ($$$$$)
+{
+ my ($version, $is_current_version, $language, $package_format, $product) = @_;
+
+ return File::Spec->catfile(
+ $ENV{'SRC_ROOT'},
+ "instsetoo_native",
+ $ENV{'INPATH'},
+ $product,
+ $package_format,
+ installer::patch::Version::ArrayToDirectoryName(
+ installer::patch::Version::StringToNumberArray($version)),
+ installer::languages::get_normalized_language($language));
+}
+
+
+
+
+sub GetMsiFilename ($$)
+{
+ my ($path, $version) = @_;
+
+ my $no_dot_version = installer::patch::Version::ArrayToNoDotName(
+ installer::patch::Version::StringToNumberArray(
+ $version));
+ return File::Spec->catfile(
+ $path,
+ "openoffice" . $no_dot_version . ".msi");
+}
+
+
+
+
+sub GetCabFilename ($$)
+{
+ my ($path, $version) = @_;
+
+ return File::Spec->catfile(
+ $path,
+ "openoffice1.cab");
+}
+
+
+
+
+=head2 Download($language, $release_data, $filename)
+
+ Download an installation set to $filename. The URL for the
+ download is taken from $release_data, a snippet from the
+ instsetoo_native/data/releases.xml file.
+
+=cut
+sub Download ($$$)
+{
+ my ($language, $release_data, $filename) = @_;
+
+ my $url = $release_data->{'URL'};
+ $release_data->{'URL'} =~ /^(.*)\/([^\/]+)$/;
+ my ($location, $basename) = ($1,$2);
+
+ $installer::logger::Info->printf("downloading %s\n", $basename);
+ $installer::logger::Info->printf(" from '%s'\n", $location);
+ my $filesize = $release_data->{'file-size'};
+ if (defined $filesize)
+ {
+ $installer::logger::Info->printf(" expected size is %d\n", $filesize);
+ }
+ else
+ {
+ $installer::logger::Info->printf(" file size is not yet known\n");
+ }
+ my $temporary_filename = $filename . ".part";
+ my $resume_size = 0;
+
+ # Prepare checksum.
+ my $checksum = undef;
+ my $checksum_type = $release_data->{'checksum-type'};
+ my $checksum_value = $release_data->{'checksum-value'};
+ my $digest = undef;
+ if ( ! defined $checksum_value)
+ {
+ # No checksum available. Skip test.
+ }
+ elsif ($checksum_type eq "sha256")
+ {
+ $digest = Digest->new("SHA-256");
+ }
+ elsif ($checksum_type eq "md5")
+ {
+ $digest = Digest->new("md5");
+ }
+ else
+ {
+ installer::logger::PrintError(
+ "checksum type %s is not supported. Supported checksum types are: sha256,md5\n",
+ $checksum_type);
+ return 0;
+ }
+
+ # Download the extension.
+ open my $out, ">$temporary_filename";
+ binmode($out);
+
+ my $mode = $|;
+ my $handle = select STDOUT;
+ $| = 1;
+ select $handle;
+
+ my $agent = LWP::UserAgent->new();
+ $agent->timeout(120);
+ $agent->show_progress(0);
+ my $last_was_redirect = 0;
+ my $bytes_read = 0;
+ $agent->add_handler('response_redirect'
+ => sub{
+ $last_was_redirect = 1;
+ return;
+ });
+ $agent->add_handler('response_data'
+ => sub{
+ if ($last_was_redirect)
+ {
+ $last_was_redirect = 0;
+ # Throw away the data we got so far.
+ $digest->reset() if defined $digest;
+ close $out;
+ open $out, ">$temporary_filename";
+ binmode($out);
+ }
+ my($response,$agent,$h,$data)=@_;
+ print $out $data;
+ $digest->add($data) if defined $digest;
+ $bytes_read += length($data);
+ if (defined $filesize)
+ {
+ printf("read %*d / %d %d%% \r",
+ length($filesize),
+ $bytes_read,
+ $filesize,
+ $bytes_read*100/$filesize);
+ }
+ else
+ {
+ printf("read %6.2f MB\r", $bytes_read/(1024.0*1024.0));
+ }
+ });
+ my $response;
+ if ($resume_size > 0)
+ {
+ $response = $agent->get($url, 'Range' => "bytes=$resume_size-");
+ }
+ else
+ {
+ $response = $agent->get($url);
+ }
+ close $out;
+
+ $handle = select STDOUT;
+ $| = $mode;
+ select $handle;
+
+ $installer::logger::Info->print(" \r");
+
+ if ($response->is_success())
+ {
+ if ( ! defined $digest
+ || $digest->hexdigest() eq $checksum_value)
+ {
+ $installer::logger::Info->print("download was successfull\n");
+ if ( ! rename($temporary_filename, $filename))
+ {
+ installer::logger::PrintError("can not rename '%s' to '%s'\n", $temporary_filename, $filename);
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+ }
+ else
+ {
+ installer::logger::PrintError("%s checksum is wrong\n", $checksum_type);
+ return 0;
+ }
+ }
+ else
+ {
+ installer::logger::PrintError("there was a download error\n");
+ return 0;
+ }
+}
+
+
+
+
+=head2 ProvideDownloadSet ($version, $language, $package_format)
+
+ Download an installation set when it is not yet present to
+ $ENV{'TARFILE_LOCATION'}. Verify the downloaded file with the
+ checksum that is extracted from the
+ instsetoo_native/data/releases.xml file.
+
+=cut
+sub ProvideDownloadSet ($$$)
+{
+ my ($version, $language, $package_format) = @_;
+
+ my $release_item = installer::patch::ReleasesList::Instance()->{$version}->{$package_format}->{$language};
+ return undef unless defined $release_item;
+
+ # Get basename of installation set from URL.
+ $release_item->{'URL'} =~ /^(.*)\/([^\/]+)$/;
+ my ($location, $basename) = ($1,$2);
+
+ # Is the installation set already present in ext_sources/ ?
+ my $need_download = 0;
+ my $ext_sources_filename = File::Spec->catfile(
+ $ENV{'TARFILE_LOCATION'},
+ $basename);
+ if ( ! -f $ext_sources_filename)
+ {
+ $installer::logger::Info->printf("download set is not in ext_sources/ (%s)\n", $ext_sources_filename);
+ $need_download = 1;
+ }
+ else
+ {
+ $installer::logger::Info->printf("download set exists at '%s'\n", $ext_sources_filename);
+ if (defined $release_item->{'checksum-value'}
+ && $release_item->{'checksum-type'} eq 'sha256')
+ {
+ $installer::logger::Info->printf("checking SHA256 checksum\n");
+ my $digest = Digest->new("SHA-256");
+ open my $in, "<", $ext_sources_filename;
+ $digest->addfile($in);
+ close $in;
+ if ($digest->hexdigest() ne $release_item->{'checksum-value'})
+ {
+ $installer::logger::Info->printf(" mismatch\n", $ext_sources_filename);
+ $need_download = 1;
+ }
+ else
+ {
+ $installer::logger::Info->printf(" match\n");
+ }
+ }
+ }
+
+ if ($need_download)
+ {
+ if ( ! installer::patch::InstallationSet::Download(
+ $language,
+ $release_item,
+ $ext_sources_filename))
+ {
+ return 0;
+ }
+ if ( ! -f $ext_sources_filename)
+ {
+ $installer::logger::Info->printf("download set could not be downloaded\n");
+ return 0;
+ }
+ }
+
+ return $ext_sources_filename;
+}
+
+
+
+
+sub ProvideUnpackedExe ($$$$$)
+{
+ my ($version, $is_current_version, $language, $package_format, $product_name) = @_;
+
+ # Check if the exe has already been unpacked.
+ my $unpacked_exe_path = installer::patch::InstallationSet::GetUnpackedExePath(
+ $version,
+ $is_current_version,
+ $language,
+ $package_format,
+ $product_name);
+ my $unpacked_exe_flag_filename = File::Spec->catfile($unpacked_exe_path, "__exe_is_unpacked");
+ my $exe_is_unpacked = -f $unpacked_exe_flag_filename;
+
+ if ($exe_is_unpacked)
+ {
+ # Yes, exe has already been unpacked. There is nothing more to do.
+ $installer::logger::Info->printf("downloadable installation set has already been unpacked to\n");
+ $installer::logger::Info->printf(" %s\n", $unpacked_exe_path);
+ return 1;
+ }
+ elsif ($is_current_version)
+ {
+ # For the current version the exe is created from the unpacked
+ # content and both are expected to be already present.
+
+ # In order to have the .cab and its unpacked content in one
+ # directory and don't interfere with the creation of regular
+ # installation sets, we copy the unpacked .exe into a separate
+ # directory.
+
+ my $original_path = File::Spec->catfile(
+ $ENV{'SRC_ROOT'},
+ "instsetoo_native",
+ $ENV{'INPATH'},
+ $product_name,
+ $package_format,
+ "install",
+ $language);
+ $installer::logger::Info->printf("creating a copy\n");
+ $installer::logger::Info->printf(" of %s\n", $original_path);
+ $installer::logger::Info->printf(" at %s\n", $unpacked_exe_path);
+ File::Path::make_path($unpacked_exe_path) unless -d $unpacked_exe_path;
+ my ($file_count,$directory_count) = CopyRecursive($original_path, $unpacked_exe_path);
+ return 0 if ( ! defined $file_count);
+ $installer::logger::Info->printf(" copied %d files in %d directories\n",
+ $file_count,
+ $directory_count);
+
+ installer::patch::Tools::touch($unpacked_exe_flag_filename);
+
+ return 1;
+ }
+ else
+ {
+ # No, we have to unpack the exe.
+
+ # Provide the exe.
+ my $filename = installer::patch::InstallationSet::ProvideDownloadSet(
+ $version,
+ $language,
+ $package_format);
+
+ # Unpack it.
+ if (defined $filename)
+ {
+ if (installer::patch::InstallationSet::UnpackExe($filename, $unpacked_exe_path))
+ {
+ $installer::logger::Info->printf("downloadable installation set has been unpacked to\n");
+ $installer::logger::Info->printf(" %s\n", $unpacked_exe_path);
+
+ installer::patch::Tools::touch($unpacked_exe_flag_filename);
+
+ return 1;
+ }
+ }
+ else
+ {
+ installer::logger::PrintError("could not provide .exe installation set at '%s'\n", $filename);
+ }
+ }
+
+ return 0;
+}
+
+
+
+
+sub CopyRecursive ($$)
+{
+ my ($source_path, $destination_path) = @_;
+
+ return (undef,undef) unless -d $source_path;
+
+ my @todo = ([$source_path, $destination_path]);
+ my $file_count = 0;
+ my $directory_count = 0;
+ while (scalar @todo > 0)
+ {
+ my ($source,$destination) = @{shift @todo};
+
+ next if ! -d $source;
+ File::Path::make_path($destination);
+ ++$directory_count;
+
+ # Read list of files in the current source directory.
+ opendir( my $dir, $source);
+ my @files = readdir $dir;
+ closedir $dir;
+
+ # Copy all files and push all directories to @todo.
+ foreach my $file (@files)
+ {
+ next if $file =~ /^\.+$/;
+
+ my $source_file = File::Spec->catfile($source, $file);
+ my $destination_file = File::Spec->catfile($destination, $file);
+ if ( -f $source_file)
+ {
+ File::Copy::copy($source_file, $destination_file);
+ ++$file_count;
+ }
+ elsif ( -d $source_file)
+ {
+ push @todo, [$source_file, $destination_file];
+ }
+ }
+ }
+
+ return ($file_count, $directory_count);
+}
+
+
+
+
+sub CheckLocalCopy ($$$$)
+{
+ my ($version, $language, $package_format, $product_name) = @_;
+
+ # Compare creation times of the original .msi and its copy.
+
+ my $original_path = File::Spec->catfile(
+ $ENV{'SRC_ROOT'},
+ "instsetoo_native",
+ $ENV{'INPATH'},
+ $product_name,
+ $package_format,
+ "install",
+ $language);
+
+ my $copy_path = installer::patch::InstallationSet::GetUnpackedExePath(
+ $version,
+ 1,
+ $language,
+ $package_format,
+ $product_name);
+
+ my $msi_basename = "openoffice"
+ . installer::patch::Version::ArrayToNoDotName(
+ installer::patch::Version::StringToNumberArray($version))
+ . ".msi";
+
+ my $original_msi_filename = File::Spec->catfile($original_path, $msi_basename);
+ my $copied_msi_filename = File::Spec->catfile($copy_path, $msi_basename);
+
+ my @original_msi_stats = stat($original_msi_filename);
+ my @copied_msi_stats = stat($copied_msi_filename);
+ my $original_msi_mtime = $original_msi_stats[9];
+ my $copied_msi_mtime = $copied_msi_stats[9];
+
+ if (defined $original_msi_mtime
+ && defined $copied_msi_mtime
+ && $original_msi_mtime > $copied_msi_mtime)
+ {
+ # The installation set is newer than its copy.
+ # Remove the copy.
+ $installer::logger::Info->printf(
+ "removing copy of installation set (version %s) because it is out of date\n",
+ $version);
+ File::Path::remove_tree($copy_path);
+ }
+}
+
+
+
+
+=head2 ProvideUnpackedCab
+
+ 1a. Make sure that a downloadable installation set is present.
+ 1b. or that a freshly built installation set (packed and unpacked is present)
+ 2. Unpack the downloadable installation set
+ 3. Unpack the .cab file.
+
+ The 'Provide' in the function name means that any step that has
+ already been made is not made again.
+
+=cut
+sub ProvideUnpackedCab ($$$$$)
+{
+ my ($version, $is_current_version, $language, $package_format, $product_name) = @_;
+
+ if ($is_current_version)
+ {
+ # For creating patches we maintain a copy of the unpacked .exe. Make sure that that is updated when
+ # a new installation set has been built.
+ CheckLocalCopy($version, $language, $package_format, $product_name);
+ }
+
+ # Check if the cab file has already been unpacked.
+ my $unpacked_cab_path = installer::patch::InstallationSet::GetUnpackedCabPath(
+ $version,
+ $is_current_version,
+ $language,
+ $package_format,
+ $product_name);
+ my $unpacked_cab_flag_filename = File::Spec->catfile($unpacked_cab_path, "__cab_is_unpacked");
+ my $cab_is_unpacked = -f $unpacked_cab_flag_filename;
+
+ if ($cab_is_unpacked)
+ {
+ # Yes. Cab was already unpacked. There is nothing more to do.
+ $installer::logger::Info->printf("cab has already been unpacked to\n");
+ $installer::logger::Info->printf(" %s\n", $unpacked_cab_path);
+
+ return 1;
+ }
+ else
+ {
+ # Make sure that the exe is unpacked and the cab file exists.
+ ProvideUnpackedExe($version, $is_current_version, $language, $package_format, $product_name);
+
+ # Unpack the cab file.
+ my $unpacked_exe_path = installer::patch::InstallationSet::GetUnpackedExePath(
+ $version,
+ $is_current_version,
+ $language,
+ $package_format,
+ $product_name);
+ my $msi = new installer::patch::Msi(
+ installer::patch::InstallationSet::GetMsiFilename($unpacked_exe_path, $version),
+ $version,
+ $is_current_version,
+ $language,
+ $product_name);
+
+ my $cab_filename = installer::patch::InstallationSet::GetCabFilename(
+ $unpacked_exe_path,
+ $version);
+ if ( ! -f $cab_filename)
+ {
+ # Cab file does not exist.
+ installer::logger::PrintError(
+ "could not find .cab file at '%s'. Extraction of .exe seems to have failed.\n",
+ $cab_filename);
+ return 0;
+ }
+
+ if (installer::patch::InstallationSet::UnpackCab(
+ $cab_filename,
+ $msi,
+ $unpacked_cab_path))
+ {
+ $installer::logger::Info->printf("unpacked cab file '%s'\n", $cab_filename);
+ $installer::logger::Info->printf(" to '%s'\n", $unpacked_cab_path);
+
+ installer::patch::Tools::touch($unpacked_cab_flag_filename);
+
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+}
+1;