1c9b362f6SAndre Fischer#************************************************************** 2c9b362f6SAndre Fischer# 3c9b362f6SAndre Fischer# Licensed to the Apache Software Foundation (ASF) under one 4c9b362f6SAndre Fischer# or more contributor license agreements. See the NOTICE file 5c9b362f6SAndre Fischer# distributed with this work for additional information 6c9b362f6SAndre Fischer# regarding copyright ownership. The ASF licenses this file 7c9b362f6SAndre Fischer# to you under the Apache License, Version 2.0 (the 8c9b362f6SAndre Fischer# "License"); you may not use this file except in compliance 9c9b362f6SAndre Fischer# with the License. You may obtain a copy of the License at 10c9b362f6SAndre Fischer# 11c9b362f6SAndre Fischer# http://www.apache.org/licenses/LICENSE-2.0 12c9b362f6SAndre Fischer# 13c9b362f6SAndre Fischer# Unless required by applicable law or agreed to in writing, 14c9b362f6SAndre Fischer# software distributed under the License is distributed on an 15c9b362f6SAndre Fischer# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16c9b362f6SAndre Fischer# KIND, either express or implied. See the License for the 17c9b362f6SAndre Fischer# specific language governing permissions and limitations 18c9b362f6SAndre Fischer# under the License. 19c9b362f6SAndre Fischer# 20c9b362f6SAndre Fischer#************************************************************** 21c9b362f6SAndre Fischer 22c9b362f6SAndre Fischerpackage installer::patch::InstallationSet; 23c9b362f6SAndre Fischer 24c9b362f6SAndre Fischeruse installer::patch::Tools; 25c9b362f6SAndre Fischeruse installer::patch::Version; 26c9b362f6SAndre Fischeruse installer::logger; 27c9b362f6SAndre Fischer 289f91b7e3SAndre Fischeruse strict; 29c9b362f6SAndre Fischer 30*677600b0SAndre Fischer# Call Get7Zip() to get access to the filename of the 7z executable. 31*677600b0SAndre Fischermy $SevenZip = undef; 329f91b7e3SAndre Fischer 339f91b7e3SAndre Fischer 34c9b362f6SAndre Fischer=head1 NAME 35c9b362f6SAndre Fischer 36c9b362f6SAndre Fischer package installer::patch::InstallationSet - Functions for handling installation sets 37c9b362f6SAndre Fischer 38c9b362f6SAndre Fischer=head1 DESCRIPTION 39c9b362f6SAndre Fischer 40c9b362f6SAndre Fischer This package contains functions for unpacking the .exe files that 41c9b362f6SAndre Fischer are created by the NSIS installer creator and the .cab files in 42c9b362f6SAndre Fischer the installation sets. 43c9b362f6SAndre Fischer 44c9b362f6SAndre Fischer=cut 45c9b362f6SAndre Fischer 46*677600b0SAndre Fischer 47*677600b0SAndre Fischer 48*677600b0SAndre Fischer 49*677600b0SAndre Fischer=head2 Detect7ZipOnWindows () 50*677600b0SAndre Fischer 51*677600b0SAndre Fischer 7Zip seems to be the only program able to unpack an NSIS installer. 52*677600b0SAndre Fischer Search for it. 53*677600b0SAndre Fischer 54*677600b0SAndre Fischer=cut 55*677600b0SAndre Fischer 56*677600b0SAndre Fischersub Detect7ZipOnWindows () 57*677600b0SAndre Fischer{ 58*677600b0SAndre Fischer # Use 'reg query' to read registry entry from Windows registry. 59*677600b0SAndre Fischer my $registry_key = "HKEY_CURRENT_USER\\\\Software\\\\7-Zip"; 60*677600b0SAndre Fischer my $registry_value_name = "Path"; 61*677600b0SAndre Fischer my $command = sprintf("reg query %s /v %s", $registry_key, $registry_value_name); 62*677600b0SAndre Fischer my $response = qx($command); 63*677600b0SAndre Fischer 64*677600b0SAndre Fischer # Process the response. 65*677600b0SAndre Fischer my $path_to_7zip = undef; 66*677600b0SAndre Fischer if ($response =~ /\s+REG_SZ\s+([^\r\n]*)/m) 67*677600b0SAndre Fischer { 68*677600b0SAndre Fischer $path_to_7zip = $1; 69*677600b0SAndre Fischer } 70*677600b0SAndre Fischer 71*677600b0SAndre Fischer # If that failed, then make an educated guess. 72*677600b0SAndre Fischer if ( ! defined $path_to_7zip) 73*677600b0SAndre Fischer { 74*677600b0SAndre Fischer $path_to_7zip = "c:\\Program Files\\7-Zip\\"; 75*677600b0SAndre Fischer } 76*677600b0SAndre Fischer 77*677600b0SAndre Fischer # Check if the executable exists and is, well, executable. 78*677600b0SAndre Fischer return undef unless -d $path_to_7zip; 79*677600b0SAndre Fischer my $fullname = File::Spec->catfile($path_to_7zip, "7z.exe"); 80*677600b0SAndre Fischer return undef unless -f $fullname; 81*677600b0SAndre Fischer return undef unless -x $fullname; 82*677600b0SAndre Fischer 83*677600b0SAndre Fischer return $fullname; 84*677600b0SAndre Fischer} 85*677600b0SAndre Fischer 86*677600b0SAndre Fischer 87*677600b0SAndre Fischer 88*677600b0SAndre Fischer 89*677600b0SAndre Fischersub Get7Zip () 90*677600b0SAndre Fischer{ 91*677600b0SAndre Fischer if ( ! defined $SevenZip) 92*677600b0SAndre Fischer { 93*677600b0SAndre Fischer if ($ENV{'OS'} eq "WNT") 94*677600b0SAndre Fischer { 95*677600b0SAndre Fischer $SevenZip = Detect7ZipOnWindows(); 96*677600b0SAndre Fischer } 97*677600b0SAndre Fischer if ( ! defined $SevenZip) 98*677600b0SAndre Fischer { 99*677600b0SAndre Fischer # Use an empty string to avoid repeated (and failing) detections of a missing 7z. 100*677600b0SAndre Fischer $SevenZip = ""; 101*677600b0SAndre Fischer } 102*677600b0SAndre Fischer } 103*677600b0SAndre Fischer 104*677600b0SAndre Fischer return $SevenZip eq "" ? undef : $SevenZip; 105*677600b0SAndre Fischer} 106*677600b0SAndre Fischer 107*677600b0SAndre Fischer 108*677600b0SAndre Fischer 109*677600b0SAndre Fischer 110c9b362f6SAndre Fischersub UnpackExe ($$) 111c9b362f6SAndre Fischer{ 112c9b362f6SAndre Fischer my ($filename, $destination_path) = @_; 113c9b362f6SAndre Fischer 114c9b362f6SAndre Fischer $installer::logger::Info->printf("unpacking installation set to '%s'\n", $destination_path); 115c9b362f6SAndre Fischer 116c9b362f6SAndre Fischer # Unpack to a temporary path and change its name to the destination path 117c9b362f6SAndre Fischer # only when the unpacking has completed successfully. 1189f91b7e3SAndre Fischer File::Path::make_path($destination_path); 119c9b362f6SAndre Fischer 1209f91b7e3SAndre Fischer my $windows_filename = installer::patch::Tools::ToEscapedWindowsPath($filename); 1219f91b7e3SAndre Fischer my $windows_destination_path = installer::patch::Tools::ToEscapedWindowsPath($destination_path); 122c9b362f6SAndre Fischer my $command = join(" ", 123*677600b0SAndre Fischer "\"".Get7Zip()."\"", 1249f91b7e3SAndre Fischer "x", 1259f91b7e3SAndre Fischer "-y", 1269f91b7e3SAndre Fischer "-o".$windows_destination_path, 127c9b362f6SAndre Fischer $windows_filename); 128c9b362f6SAndre Fischer my $result = qx($command); 129*677600b0SAndre Fischer if ( ! $result) 130*677600b0SAndre Fischer { 131*677600b0SAndre Fischer installer::exiter::exit_program( 132*677600b0SAndre Fischer "ERROR: can not unpack downloadable installation set: ".$!, 133*677600b0SAndre Fischer "installer::patch::InstallationSet::UnpackExe"); 134*677600b0SAndre Fischer } 135c9b362f6SAndre Fischer 136c9b362f6SAndre Fischer # Check the existence of the .cab files. 1379f91b7e3SAndre Fischer my $cab_filename = File::Spec->catfile($destination_path, "openoffice1.cab"); 138c9b362f6SAndre Fischer if ( ! -f $cab_filename) 139c9b362f6SAndre Fischer { 140c9b362f6SAndre Fischer installer::logger::PrintError("cab file '%s' was not extracted from installation set\n", $cab_filename); 141c9b362f6SAndre Fischer return 0; 142c9b362f6SAndre Fischer } 143c9b362f6SAndre Fischer return 1; 144c9b362f6SAndre Fischer} 145c9b362f6SAndre Fischer 146c9b362f6SAndre Fischer 147c9b362f6SAndre Fischer 148c9b362f6SAndre Fischer 149c9b362f6SAndre Fischer=head2 UnpackCab($cab_filename, $destination_path) 150c9b362f6SAndre Fischer 151c9b362f6SAndre Fischer Unpacking the cabinet file inside an .exe installation set is a 152c9b362f6SAndre Fischer three step process because there is no directory information stored 153c9b362f6SAndre Fischer inside the cab file. This has to be taken from the 'File' and 154c9b362f6SAndre Fischer 'Directory' tables in the .msi file. 155c9b362f6SAndre Fischer 156c9b362f6SAndre Fischer 1. Setup the directory structure of all files in the cab from the 'File' and 'Directory' tables in the msi. 157c9b362f6SAndre Fischer 158c9b362f6SAndre Fischer 2. Unpack the cab file. 159c9b362f6SAndre Fischer 160c9b362f6SAndre Fischer 3. Move the files to their destination directories. 161c9b362f6SAndre Fischer 162c9b362f6SAndre Fischer=cut 163c9b362f6SAndre Fischersub UnpackCab ($$$) 164c9b362f6SAndre Fischer{ 165c9b362f6SAndre Fischer my ($cab_filename, $msi, $destination_path) = @_; 166c9b362f6SAndre Fischer 167c9b362f6SAndre Fischer # Step 1 168c9b362f6SAndre Fischer # Extract the directory structure from the 'File' and 'Directory' tables in the given msi. 169c9b362f6SAndre Fischer $installer::logger::Info->printf("setting up directory tree\n"); 170c9b362f6SAndre Fischer my $file_table = $msi->GetTable("File"); 1719f91b7e3SAndre Fischer my $file_map = $msi->GetFileMap(); 172c9b362f6SAndre Fischer 173c9b362f6SAndre Fischer # Step 2 174c9b362f6SAndre Fischer # Unpack the .cab file to a temporary path. 175c9b362f6SAndre Fischer my $temporary_destination_path = $destination_path . ".tmp"; 176c9b362f6SAndre Fischer if ( -d $temporary_destination_path) 177c9b362f6SAndre Fischer { 178c9b362f6SAndre Fischer # Temporary directory already exists => cab file has already been unpacked (flat), nothing to do. 179*677600b0SAndre Fischer printf("%s exists\n", $temporary_destination_path); 180c9b362f6SAndre Fischer $installer::logger::Info->printf("cab file has already been unpacked to flat structure\n"); 181c9b362f6SAndre Fischer } 182c9b362f6SAndre Fischer else 183c9b362f6SAndre Fischer { 184c9b362f6SAndre Fischer UnpackCabFlat($cab_filename, $temporary_destination_path, $file_table); 185c9b362f6SAndre Fischer } 186c9b362f6SAndre Fischer 187c9b362f6SAndre Fischer # Step 3 188c9b362f6SAndre Fischer # Move the files to their destinations. 189c9b362f6SAndre Fischer File::Path::make_path($destination_path); 190c9b362f6SAndre Fischer $installer::logger::Info->printf("moving files to their directories\n"); 191*677600b0SAndre Fischer my $directory_map = $msi->GetDirectoryMap(); 192*677600b0SAndre Fischer my $office_menu_folder_name = $directory_map->{'INSTALLLOCATION'}->{'target_long_name'}; 193c9b362f6SAndre Fischer my $count = 0; 194c9b362f6SAndre Fischer foreach my $file_row (@{$file_table->GetAllRows()}) 195c9b362f6SAndre Fischer { 196c9b362f6SAndre Fischer my $unique_name = $file_row->GetValue('File'); 197*677600b0SAndre Fischer my $file_item = $file_map->{$unique_name}; 198*677600b0SAndre Fischer my $directory_item = $file_item->{'directory'}; 199*677600b0SAndre Fischer my $long_file_name = $file_item->{'long_name'}; 200*677600b0SAndre Fischer my $full_name = $directory_item->{'full_source_long_name'}; 201*677600b0SAndre Fischer # Strip away the leading OfficeMenuFolder part. 202*677600b0SAndre Fischer $full_name =~ s/^$office_menu_folder_name\///; 203c9b362f6SAndre Fischer my $flat_filename = File::Spec->catfile($temporary_destination_path, $unique_name); 204*677600b0SAndre Fischer my $dir_path = File::Spec->catfile($destination_path, $full_name); 205*677600b0SAndre Fischer my $dir_filename = File::Spec->catfile($dir_path, $long_file_name); 206c9b362f6SAndre Fischer 2079f91b7e3SAndre Fischer if ( ! -d $dir_path) 2089f91b7e3SAndre Fischer { 209c9b362f6SAndre Fischer File::Path::make_path($dir_path); 2109f91b7e3SAndre Fischer } 211*677600b0SAndre Fischer 212*677600b0SAndre Fischer $installer::logger::Lang->printf("moving %s to %s\n", $flat_filename, $dir_filename); 213*677600b0SAndre Fischer File::Copy::move($flat_filename, $dir_filename) 214*677600b0SAndre Fischer || die("can not move file ".$flat_filename.":".$!); 215c9b362f6SAndre Fischer 216c9b362f6SAndre Fischer ++$count; 217c9b362f6SAndre Fischer } 218c9b362f6SAndre Fischer 219c9b362f6SAndre Fischer # Cleanup. Remove the temporary directory. It should be empty by now. 220c9b362f6SAndre Fischer rmdir($temporary_destination_path); 221c9b362f6SAndre Fischer} 222c9b362f6SAndre Fischer 223c9b362f6SAndre Fischer 224c9b362f6SAndre Fischer 225c9b362f6SAndre Fischer 226c9b362f6SAndre Fischer=head2 UnpackCabFlat ($cab_filename, $destination_path, $file_table) 227c9b362f6SAndre Fischer 228c9b362f6SAndre Fischer Unpack the flat file structure of the $cab_filename to $destination_path. 229c9b362f6SAndre Fischer 230c9b362f6SAndre Fischer In order to detect and handle an incomplete (arborted) previous 231c9b362f6SAndre Fischer extraction, the cab file is unpacked to a temprorary directory 232c9b362f6SAndre Fischer that after successful extraction is renamed to $destination_path. 233c9b362f6SAndre Fischer 234c9b362f6SAndre Fischer=cut 235c9b362f6SAndre Fischersub UnpackCabFlat ($$$) 236c9b362f6SAndre Fischer{ 237c9b362f6SAndre Fischer my ($cab_filename, $destination_path, $file_table) = @_; 238c9b362f6SAndre Fischer 239c9b362f6SAndre Fischer # Unpack the .cab file to a temporary path (note that 240c9b362f6SAndre Fischer # $destination_path may alreay bee a temporary path). Using a 241c9b362f6SAndre Fischer # second one prevents the lengthy flat unpacking to be repeated 242c9b362f6SAndre Fischer # when another step fails. 243c9b362f6SAndre Fischer 244c9b362f6SAndre Fischer $installer::logger::Info->printf("unpacking cab file\n"); 2459f91b7e3SAndre Fischer File::Path::make_path($destination_path); 2469f91b7e3SAndre Fischer my $windows_cab_filename = installer::patch::Tools::ToEscapedWindowsPath($cab_filename); 2479f91b7e3SAndre Fischer my $windows_destination_path = installer::patch::Tools::ToEscapedWindowsPath($destination_path); 248c9b362f6SAndre Fischer my $command = join(" ", 249*677600b0SAndre Fischer "\"".Get7Zip()."\"", 250c9b362f6SAndre Fischer "x", "-o".$windows_destination_path, 251c9b362f6SAndre Fischer $windows_cab_filename, 252c9b362f6SAndre Fischer "-y"); 253c9b362f6SAndre Fischer open my $cmd, $command."|"; 254c9b362f6SAndre Fischer my $extraction_count = 0; 255c9b362f6SAndre Fischer my $file_count = $file_table->GetRowCount(); 256c9b362f6SAndre Fischer while (<$cmd>) 257c9b362f6SAndre Fischer { 258c9b362f6SAndre Fischer my $message = $_; 259c9b362f6SAndre Fischer chomp($message); 260c9b362f6SAndre Fischer ++$extraction_count; 261c9b362f6SAndre Fischer printf("%4d/%4d %3.2f%% \r", 262c9b362f6SAndre Fischer $extraction_count, 263c9b362f6SAndre Fischer $file_count, 264c9b362f6SAndre Fischer $extraction_count*100/$file_count); 265c9b362f6SAndre Fischer } 266c9b362f6SAndre Fischer close $cmd; 267c9b362f6SAndre Fischer} 268c9b362f6SAndre Fischer 269c9b362f6SAndre Fischer 270c9b362f6SAndre Fischer 271c9b362f6SAndre Fischer 2729f91b7e3SAndre Fischer=head GetUnpackedExePath ($version, $is_current_version, $language, $package_format, $product) 273c9b362f6SAndre Fischer 274c9b362f6SAndre Fischer Convenience function that returns where a downloadable installation set is extracted to. 275c9b362f6SAndre Fischer 276c9b362f6SAndre Fischer=cut 2779f91b7e3SAndre Fischersub GetUnpackedExePath ($$$$$) 278c9b362f6SAndre Fischer{ 2799f91b7e3SAndre Fischer my ($version, $is_current_version, $language, $package_format, $product) = @_; 280c9b362f6SAndre Fischer 2819f91b7e3SAndre Fischer my $path = GetUnpackedPath($version, $is_current_version, $language, $package_format, $product); 2829f91b7e3SAndre Fischer return File::Spec->catfile($path, "unpacked"); 283c9b362f6SAndre Fischer} 284c9b362f6SAndre Fischer 285c9b362f6SAndre Fischer 286c9b362f6SAndre Fischer 287c9b362f6SAndre Fischer 2889f91b7e3SAndre Fischer=head GetUnpackedCabPath ($version, $is_current_version, $language, $package_format, $product) 289c9b362f6SAndre Fischer 290c9b362f6SAndre Fischer Convenience function that returns where a cab file is extracted 291c9b362f6SAndre Fischer (with injected directory structure from the msi file) to. 292c9b362f6SAndre Fischer 293c9b362f6SAndre Fischer=cut 2949f91b7e3SAndre Fischersub GetUnpackedCabPath ($$$$$) 295c9b362f6SAndre Fischer{ 2969f91b7e3SAndre Fischer my ($version, $is_current_version, $language, $package_format, $product) = @_; 297c9b362f6SAndre Fischer 2989f91b7e3SAndre Fischer my $path = GetUnpackedPath($version, $is_current_version, $language, $package_format, $product); 2999f91b7e3SAndre Fischer return File::Spec->catfile($path, "unpacked"); 300c9b362f6SAndre Fischer} 301c9b362f6SAndre Fischer 302c9b362f6SAndre Fischer 303c9b362f6SAndre Fischer 304c9b362f6SAndre Fischer 3059f91b7e3SAndre Fischer=head2 GetUnpackedPath($version, $is_current_version, $language, $package_format, $product) 306c9b362f6SAndre Fischer 307c9b362f6SAndre Fischer Internal function for creating paths to where archives are unpacked. 308c9b362f6SAndre Fischer 309c9b362f6SAndre Fischer=cut 3109f91b7e3SAndre Fischersub GetUnpackedPath ($$$$$) 311c9b362f6SAndre Fischer{ 3129f91b7e3SAndre Fischer my ($version, $is_current_version, $language, $package_format, $product) = @_; 313c9b362f6SAndre Fischer 314c9b362f6SAndre Fischer return File::Spec->catfile( 315c9b362f6SAndre Fischer $ENV{'SRC_ROOT'}, 316c9b362f6SAndre Fischer "instsetoo_native", 317c9b362f6SAndre Fischer $ENV{'INPATH'}, 318c9b362f6SAndre Fischer $product, 319c9b362f6SAndre Fischer $package_format, 3209f91b7e3SAndre Fischer installer::patch::Version::ArrayToDirectoryName( 3219f91b7e3SAndre Fischer installer::patch::Version::StringToNumberArray($version)), 32260b96b8dSAndre Fischer installer::languages::get_normalized_language($language)); 323c9b362f6SAndre Fischer} 324c9b362f6SAndre Fischer 325c9b362f6SAndre Fischer 326c9b362f6SAndre Fischer 327c9b362f6SAndre Fischer 3289f91b7e3SAndre Fischersub GetMsiFilename ($$) 3299f91b7e3SAndre Fischer{ 3309f91b7e3SAndre Fischer my ($path, $version) = @_; 3319f91b7e3SAndre Fischer 3329f91b7e3SAndre Fischer my $no_dot_version = installer::patch::Version::ArrayToNoDotName( 3339f91b7e3SAndre Fischer installer::patch::Version::StringToNumberArray( 3349f91b7e3SAndre Fischer $version)); 3359f91b7e3SAndre Fischer return File::Spec->catfile( 3369f91b7e3SAndre Fischer $path, 3379f91b7e3SAndre Fischer "openoffice" . $no_dot_version . ".msi"); 3389f91b7e3SAndre Fischer} 3399f91b7e3SAndre Fischer 3409f91b7e3SAndre Fischer 3419f91b7e3SAndre Fischer 3429f91b7e3SAndre Fischer 3439f91b7e3SAndre Fischersub GetCabFilename ($$) 3449f91b7e3SAndre Fischer{ 3459f91b7e3SAndre Fischer my ($path, $version) = @_; 3469f91b7e3SAndre Fischer 3479f91b7e3SAndre Fischer return File::Spec->catfile( 3489f91b7e3SAndre Fischer $path, 3499f91b7e3SAndre Fischer "openoffice1.cab"); 3509f91b7e3SAndre Fischer} 3519f91b7e3SAndre Fischer 3529f91b7e3SAndre Fischer 3539f91b7e3SAndre Fischer 3549f91b7e3SAndre Fischer 355c9b362f6SAndre Fischer=head2 Download($language, $release_data, $filename) 356c9b362f6SAndre Fischer 357c9b362f6SAndre Fischer Download an installation set to $filename. The URL for the 358c9b362f6SAndre Fischer download is taken from $release_data, a snippet from the 359c9b362f6SAndre Fischer instsetoo_native/data/releases.xml file. 360c9b362f6SAndre Fischer 361c9b362f6SAndre Fischer=cut 362c9b362f6SAndre Fischersub Download ($$$) 363c9b362f6SAndre Fischer{ 364c9b362f6SAndre Fischer my ($language, $release_data, $filename) = @_; 365c9b362f6SAndre Fischer 366c9b362f6SAndre Fischer my $url = $release_data->{'URL'}; 367c9b362f6SAndre Fischer $release_data->{'URL'} =~ /^(.*)\/([^\/]+)$/; 368c9b362f6SAndre Fischer my ($location, $basename) = ($1,$2); 369c9b362f6SAndre Fischer 370c9b362f6SAndre Fischer $installer::logger::Info->printf("downloading %s\n", $basename); 371c9b362f6SAndre Fischer $installer::logger::Info->printf(" from '%s'\n", $location); 372c9b362f6SAndre Fischer my $filesize = $release_data->{'file-size'}; 373d575d58fSAndre Fischer if (defined $filesize) 374d575d58fSAndre Fischer { 375c9b362f6SAndre Fischer $installer::logger::Info->printf(" expected size is %d\n", $filesize); 376d575d58fSAndre Fischer } 377d575d58fSAndre Fischer else 378d575d58fSAndre Fischer { 379d575d58fSAndre Fischer $installer::logger::Info->printf(" file size is not yet known\n"); 380d575d58fSAndre Fischer } 381c9b362f6SAndre Fischer my $temporary_filename = $filename . ".part"; 382c9b362f6SAndre Fischer my $resume_size = 0; 383c9b362f6SAndre Fischer 384c9b362f6SAndre Fischer # Prepare checksum. 385c9b362f6SAndre Fischer my $checksum = undef; 386c9b362f6SAndre Fischer my $checksum_type = $release_data->{'checksum-type'}; 387c9b362f6SAndre Fischer my $checksum_value = $release_data->{'checksum-value'}; 388c9b362f6SAndre Fischer my $digest = undef; 389d575d58fSAndre Fischer if ( ! defined $checksum_value) 390d575d58fSAndre Fischer { 391d575d58fSAndre Fischer # No checksum available. Skip test. 392d575d58fSAndre Fischer } 393d575d58fSAndre Fischer elsif ($checksum_type eq "sha256") 394c9b362f6SAndre Fischer { 395c9b362f6SAndre Fischer $digest = Digest->new("SHA-256"); 396c9b362f6SAndre Fischer } 397c9b362f6SAndre Fischer elsif ($checksum_type eq "md5") 398c9b362f6SAndre Fischer { 399c9b362f6SAndre Fischer $digest = Digest->new("md5"); 400c9b362f6SAndre Fischer } 401c9b362f6SAndre Fischer else 402c9b362f6SAndre Fischer { 403c9b362f6SAndre Fischer installer::logger::PrintError( 404c9b362f6SAndre Fischer "checksum type %s is not supported. Supported checksum types are: sha256,md5\n", 405c9b362f6SAndre Fischer $checksum_type); 406c9b362f6SAndre Fischer return 0; 407c9b362f6SAndre Fischer } 408c9b362f6SAndre Fischer 409c9b362f6SAndre Fischer # Download the extension. 410d575d58fSAndre Fischer open my $out, ">$temporary_filename"; 411c9b362f6SAndre Fischer binmode($out); 412c9b362f6SAndre Fischer 413c9b362f6SAndre Fischer my $mode = $|; 414c9b362f6SAndre Fischer my $handle = select STDOUT; 415c9b362f6SAndre Fischer $| = 1; 416c9b362f6SAndre Fischer select $handle; 417c9b362f6SAndre Fischer 418c9b362f6SAndre Fischer my $agent = LWP::UserAgent->new(); 419c9b362f6SAndre Fischer $agent->timeout(120); 420c9b362f6SAndre Fischer $agent->show_progress(0); 421c9b362f6SAndre Fischer my $last_was_redirect = 0; 422c9b362f6SAndre Fischer my $bytes_read = 0; 423c9b362f6SAndre Fischer $agent->add_handler('response_redirect' 424c9b362f6SAndre Fischer => sub{ 425c9b362f6SAndre Fischer $last_was_redirect = 1; 426c9b362f6SAndre Fischer return; 427c9b362f6SAndre Fischer }); 428c9b362f6SAndre Fischer $agent->add_handler('response_data' 429c9b362f6SAndre Fischer => sub{ 430c9b362f6SAndre Fischer if ($last_was_redirect) 431c9b362f6SAndre Fischer { 432c9b362f6SAndre Fischer $last_was_redirect = 0; 433c9b362f6SAndre Fischer # Throw away the data we got so far. 434d575d58fSAndre Fischer $digest->reset() if defined $digest; 435c9b362f6SAndre Fischer close $out; 436c9b362f6SAndre Fischer open $out, ">$temporary_filename"; 437c9b362f6SAndre Fischer binmode($out); 438c9b362f6SAndre Fischer } 439c9b362f6SAndre Fischer my($response,$agent,$h,$data)=@_; 440c9b362f6SAndre Fischer print $out $data; 441d575d58fSAndre Fischer $digest->add($data) if defined $digest; 442c9b362f6SAndre Fischer $bytes_read += length($data); 443d575d58fSAndre Fischer if (defined $filesize) 444d575d58fSAndre Fischer { 445c9b362f6SAndre Fischer printf("read %*d / %d %d%% \r", 446c9b362f6SAndre Fischer length($filesize), 447c9b362f6SAndre Fischer $bytes_read, 448c9b362f6SAndre Fischer $filesize, 449c9b362f6SAndre Fischer $bytes_read*100/$filesize); 450d575d58fSAndre Fischer } 451d575d58fSAndre Fischer else 452d575d58fSAndre Fischer { 453d575d58fSAndre Fischer printf("read %6.2f MB\r", $bytes_read/(1024.0*1024.0)); 454d575d58fSAndre Fischer } 455c9b362f6SAndre Fischer }); 456c9b362f6SAndre Fischer my $response; 457c9b362f6SAndre Fischer if ($resume_size > 0) 458c9b362f6SAndre Fischer { 459c9b362f6SAndre Fischer $response = $agent->get($url, 'Range' => "bytes=$resume_size-"); 460c9b362f6SAndre Fischer } 461c9b362f6SAndre Fischer else 462c9b362f6SAndre Fischer { 463c9b362f6SAndre Fischer $response = $agent->get($url); 464c9b362f6SAndre Fischer } 465c9b362f6SAndre Fischer close $out; 466c9b362f6SAndre Fischer 467c9b362f6SAndre Fischer $handle = select STDOUT; 468c9b362f6SAndre Fischer $| = $mode; 469c9b362f6SAndre Fischer select $handle; 470c9b362f6SAndre Fischer 471c9b362f6SAndre Fischer $installer::logger::Info->print(" \r"); 472c9b362f6SAndre Fischer 473c9b362f6SAndre Fischer if ($response->is_success()) 474c9b362f6SAndre Fischer { 475d575d58fSAndre Fischer if ( ! defined $digest 476d575d58fSAndre Fischer || $digest->hexdigest() eq $checksum_value) 477c9b362f6SAndre Fischer { 478d575d58fSAndre Fischer $installer::logger::Info->print("download was successfull\n"); 479c9b362f6SAndre Fischer if ( ! rename($temporary_filename, $filename)) 480c9b362f6SAndre Fischer { 481c9b362f6SAndre Fischer installer::logger::PrintError("can not rename '%s' to '%s'\n", $temporary_filename, $filename); 482c9b362f6SAndre Fischer return 0; 483c9b362f6SAndre Fischer } 484c9b362f6SAndre Fischer else 485c9b362f6SAndre Fischer { 486c9b362f6SAndre Fischer return 1; 487c9b362f6SAndre Fischer } 488c9b362f6SAndre Fischer } 489c9b362f6SAndre Fischer else 490c9b362f6SAndre Fischer { 491c9b362f6SAndre Fischer installer::logger::PrintError("%s checksum is wrong\n", $checksum_type); 492c9b362f6SAndre Fischer return 0; 493c9b362f6SAndre Fischer } 494c9b362f6SAndre Fischer } 495c9b362f6SAndre Fischer else 496c9b362f6SAndre Fischer { 497c9b362f6SAndre Fischer installer::logger::PrintError("there was a download error\n"); 498c9b362f6SAndre Fischer return 0; 499c9b362f6SAndre Fischer } 500c9b362f6SAndre Fischer} 501c9b362f6SAndre Fischer 502c9b362f6SAndre Fischer 503c9b362f6SAndre Fischer 504c9b362f6SAndre Fischer 505c9b362f6SAndre Fischer=head2 ProvideDownloadSet ($version, $language, $package_format) 506c9b362f6SAndre Fischer 507c9b362f6SAndre Fischer Download an installation set when it is not yet present to 508c9b362f6SAndre Fischer $ENV{'TARFILE_LOCATION'}. Verify the downloaded file with the 509c9b362f6SAndre Fischer checksum that is extracted from the 510c9b362f6SAndre Fischer instsetoo_native/data/releases.xml file. 511c9b362f6SAndre Fischer 512c9b362f6SAndre Fischer=cut 513c9b362f6SAndre Fischersub ProvideDownloadSet ($$$) 514c9b362f6SAndre Fischer{ 515c9b362f6SAndre Fischer my ($version, $language, $package_format) = @_; 516c9b362f6SAndre Fischer 517c9b362f6SAndre Fischer my $release_item = installer::patch::ReleasesList::Instance()->{$version}->{$package_format}->{$language}; 518*677600b0SAndre Fischer return undef unless defined $release_item; 519c9b362f6SAndre Fischer 520c9b362f6SAndre Fischer # Get basename of installation set from URL. 521c9b362f6SAndre Fischer $release_item->{'URL'} =~ /^(.*)\/([^\/]+)$/; 522c9b362f6SAndre Fischer my ($location, $basename) = ($1,$2); 523c9b362f6SAndre Fischer 524c9b362f6SAndre Fischer # Is the installation set already present in ext_sources/ ? 525c9b362f6SAndre Fischer my $need_download = 0; 526c9b362f6SAndre Fischer my $ext_sources_filename = File::Spec->catfile( 527c9b362f6SAndre Fischer $ENV{'TARFILE_LOCATION'}, 528c9b362f6SAndre Fischer $basename); 529c9b362f6SAndre Fischer if ( ! -f $ext_sources_filename) 530c9b362f6SAndre Fischer { 531c9b362f6SAndre Fischer $installer::logger::Info->printf("download set is not in ext_sources/ (%s)\n", $ext_sources_filename); 532c9b362f6SAndre Fischer $need_download = 1; 533c9b362f6SAndre Fischer } 534c9b362f6SAndre Fischer else 535c9b362f6SAndre Fischer { 536c9b362f6SAndre Fischer $installer::logger::Info->printf("download set exists at '%s'\n", $ext_sources_filename); 537d575d58fSAndre Fischer if (defined $release_item->{'checksum-value'} 538d575d58fSAndre Fischer && $release_item->{'checksum-type'} eq 'sha256') 539c9b362f6SAndre Fischer { 540c9b362f6SAndre Fischer $installer::logger::Info->printf("checking SHA256 checksum\n"); 541c9b362f6SAndre Fischer my $digest = Digest->new("SHA-256"); 542c9b362f6SAndre Fischer open my $in, "<", $ext_sources_filename; 543c9b362f6SAndre Fischer $digest->addfile($in); 544c9b362f6SAndre Fischer close $in; 545c9b362f6SAndre Fischer if ($digest->hexdigest() ne $release_item->{'checksum-value'}) 546c9b362f6SAndre Fischer { 547c9b362f6SAndre Fischer $installer::logger::Info->printf(" mismatch\n", $ext_sources_filename); 548c9b362f6SAndre Fischer $need_download = 1; 549c9b362f6SAndre Fischer } 550c9b362f6SAndre Fischer else 551c9b362f6SAndre Fischer { 552c9b362f6SAndre Fischer $installer::logger::Info->printf(" match\n"); 553c9b362f6SAndre Fischer } 554c9b362f6SAndre Fischer } 555c9b362f6SAndre Fischer } 556c9b362f6SAndre Fischer 557c9b362f6SAndre Fischer if ($need_download) 558c9b362f6SAndre Fischer { 559c9b362f6SAndre Fischer if ( ! installer::patch::InstallationSet::Download( 560c9b362f6SAndre Fischer $language, 561c9b362f6SAndre Fischer $release_item, 562c9b362f6SAndre Fischer $ext_sources_filename)) 563c9b362f6SAndre Fischer { 564c9b362f6SAndre Fischer return 0; 565c9b362f6SAndre Fischer } 566c9b362f6SAndre Fischer if ( ! -f $ext_sources_filename) 567c9b362f6SAndre Fischer { 568c9b362f6SAndre Fischer $installer::logger::Info->printf("download set could not be downloaded\n"); 569c9b362f6SAndre Fischer return 0; 570c9b362f6SAndre Fischer } 571c9b362f6SAndre Fischer } 572c9b362f6SAndre Fischer 573c9b362f6SAndre Fischer return $ext_sources_filename; 574c9b362f6SAndre Fischer} 575c9b362f6SAndre Fischer 5769f91b7e3SAndre Fischer 5779f91b7e3SAndre Fischer 5789f91b7e3SAndre Fischer 5799f91b7e3SAndre Fischersub ProvideUnpackedExe ($$$$$) 5809f91b7e3SAndre Fischer{ 5819f91b7e3SAndre Fischer my ($version, $is_current_version, $language, $package_format, $product_name) = @_; 5829f91b7e3SAndre Fischer 5839f91b7e3SAndre Fischer # Check if the exe has already been unpacked. 5849f91b7e3SAndre Fischer my $unpacked_exe_path = installer::patch::InstallationSet::GetUnpackedExePath( 5859f91b7e3SAndre Fischer $version, 5869f91b7e3SAndre Fischer $is_current_version, 5879f91b7e3SAndre Fischer $language, 5889f91b7e3SAndre Fischer $package_format, 5899f91b7e3SAndre Fischer $product_name); 5909f91b7e3SAndre Fischer my $unpacked_exe_flag_filename = File::Spec->catfile($unpacked_exe_path, "__exe_is_unpacked"); 5919f91b7e3SAndre Fischer my $exe_is_unpacked = -f $unpacked_exe_flag_filename; 5929f91b7e3SAndre Fischer 5939f91b7e3SAndre Fischer if ($exe_is_unpacked) 5949f91b7e3SAndre Fischer { 5959f91b7e3SAndre Fischer # Yes, exe has already been unpacked. There is nothing more to do. 5969f91b7e3SAndre Fischer $installer::logger::Info->printf("downloadable installation set has already been unpacked to\n"); 5979f91b7e3SAndre Fischer $installer::logger::Info->printf(" %s\n", $unpacked_exe_path); 5989f91b7e3SAndre Fischer return 1; 5999f91b7e3SAndre Fischer } 6009f91b7e3SAndre Fischer elsif ($is_current_version) 6019f91b7e3SAndre Fischer { 6029f91b7e3SAndre Fischer # For the current version the exe is created from the unpacked 6039f91b7e3SAndre Fischer # content and both are expected to be already present. 6049f91b7e3SAndre Fischer 6059f91b7e3SAndre Fischer # In order to have the .cab and its unpacked content in one 6069f91b7e3SAndre Fischer # directory and don't interfere with the creation of regular 6079f91b7e3SAndre Fischer # installation sets, we copy the unpacked .exe into a separate 6089f91b7e3SAndre Fischer # directory. 6099f91b7e3SAndre Fischer 6109f91b7e3SAndre Fischer my $original_path = File::Spec->catfile( 6119f91b7e3SAndre Fischer $ENV{'SRC_ROOT'}, 6129f91b7e3SAndre Fischer "instsetoo_native", 6139f91b7e3SAndre Fischer $ENV{'INPATH'}, 6149f91b7e3SAndre Fischer $product_name, 6159f91b7e3SAndre Fischer $package_format, 6169f91b7e3SAndre Fischer "install", 6179f91b7e3SAndre Fischer $language); 6189f91b7e3SAndre Fischer $installer::logger::Info->printf("creating a copy\n"); 6199f91b7e3SAndre Fischer $installer::logger::Info->printf(" of %s\n", $original_path); 6209f91b7e3SAndre Fischer $installer::logger::Info->printf(" at %s\n", $unpacked_exe_path); 6219f91b7e3SAndre Fischer File::Path::make_path($unpacked_exe_path) unless -d $unpacked_exe_path; 6229f91b7e3SAndre Fischer my ($file_count,$directory_count) = CopyRecursive($original_path, $unpacked_exe_path); 6239f91b7e3SAndre Fischer return 0 if ( ! defined $file_count); 6249f91b7e3SAndre Fischer $installer::logger::Info->printf(" copied %d files in %d directories\n", 6259f91b7e3SAndre Fischer $file_count, 6269f91b7e3SAndre Fischer $directory_count); 6279f91b7e3SAndre Fischer 628*677600b0SAndre Fischer installer::patch::Tools::touch($unpacked_exe_flag_filename); 6299f91b7e3SAndre Fischer 6309f91b7e3SAndre Fischer return 1; 6319f91b7e3SAndre Fischer } 6329f91b7e3SAndre Fischer else 6339f91b7e3SAndre Fischer { 6349f91b7e3SAndre Fischer # No, we have to unpack the exe. 6359f91b7e3SAndre Fischer 6369f91b7e3SAndre Fischer # Provide the exe. 6379f91b7e3SAndre Fischer my $filename = installer::patch::InstallationSet::ProvideDownloadSet( 6389f91b7e3SAndre Fischer $version, 6399f91b7e3SAndre Fischer $language, 6409f91b7e3SAndre Fischer $package_format); 6419f91b7e3SAndre Fischer 6429f91b7e3SAndre Fischer # Unpack it. 6439f91b7e3SAndre Fischer if (defined $filename) 6449f91b7e3SAndre Fischer { 6459f91b7e3SAndre Fischer if (installer::patch::InstallationSet::UnpackExe($filename, $unpacked_exe_path)) 6469f91b7e3SAndre Fischer { 6479f91b7e3SAndre Fischer $installer::logger::Info->printf("downloadable installation set has been unpacked to\n"); 6489f91b7e3SAndre Fischer $installer::logger::Info->printf(" %s\n", $unpacked_exe_path); 6499f91b7e3SAndre Fischer 650*677600b0SAndre Fischer installer::patch::Tools::touch($unpacked_exe_flag_filename); 6519f91b7e3SAndre Fischer 6529f91b7e3SAndre Fischer return 1; 6539f91b7e3SAndre Fischer } 6549f91b7e3SAndre Fischer } 6559f91b7e3SAndre Fischer else 6569f91b7e3SAndre Fischer { 6579f91b7e3SAndre Fischer installer::logger::PrintError("could not provide .exe installation set at '%s'\n", $filename); 6589f91b7e3SAndre Fischer } 6599f91b7e3SAndre Fischer } 6609f91b7e3SAndre Fischer 6619f91b7e3SAndre Fischer return 0; 6629f91b7e3SAndre Fischer} 6639f91b7e3SAndre Fischer 6649f91b7e3SAndre Fischer 6659f91b7e3SAndre Fischer 6669f91b7e3SAndre Fischer 6679f91b7e3SAndre Fischersub CopyRecursive ($$) 6689f91b7e3SAndre Fischer{ 6699f91b7e3SAndre Fischer my ($source_path, $destination_path) = @_; 6709f91b7e3SAndre Fischer 6719f91b7e3SAndre Fischer return (undef,undef) unless -d $source_path; 6729f91b7e3SAndre Fischer 6739f91b7e3SAndre Fischer my @todo = ([$source_path, $destination_path]); 6749f91b7e3SAndre Fischer my $file_count = 0; 6759f91b7e3SAndre Fischer my $directory_count = 0; 6769f91b7e3SAndre Fischer while (scalar @todo > 0) 6779f91b7e3SAndre Fischer { 6789f91b7e3SAndre Fischer my ($source,$destination) = @{shift @todo}; 6799f91b7e3SAndre Fischer 6809f91b7e3SAndre Fischer next if ! -d $source; 6819f91b7e3SAndre Fischer File::Path::make_path($destination); 6829f91b7e3SAndre Fischer ++$directory_count; 6839f91b7e3SAndre Fischer 6849f91b7e3SAndre Fischer # Read list of files in the current source directory. 6859f91b7e3SAndre Fischer opendir( my $dir, $source); 6869f91b7e3SAndre Fischer my @files = readdir $dir; 6879f91b7e3SAndre Fischer closedir $dir; 6889f91b7e3SAndre Fischer 6899f91b7e3SAndre Fischer # Copy all files and push all directories to @todo. 6909f91b7e3SAndre Fischer foreach my $file (@files) 6919f91b7e3SAndre Fischer { 6929f91b7e3SAndre Fischer next if $file =~ /^\.+$/; 6939f91b7e3SAndre Fischer 6949f91b7e3SAndre Fischer my $source_file = File::Spec->catfile($source, $file); 6959f91b7e3SAndre Fischer my $destination_file = File::Spec->catfile($destination, $file); 6969f91b7e3SAndre Fischer if ( -f $source_file) 6979f91b7e3SAndre Fischer { 6989f91b7e3SAndre Fischer File::Copy::copy($source_file, $destination_file); 6999f91b7e3SAndre Fischer ++$file_count; 7009f91b7e3SAndre Fischer } 7019f91b7e3SAndre Fischer elsif ( -d $source_file) 7029f91b7e3SAndre Fischer { 7039f91b7e3SAndre Fischer push @todo, [$source_file, $destination_file]; 7049f91b7e3SAndre Fischer } 7059f91b7e3SAndre Fischer } 7069f91b7e3SAndre Fischer } 7079f91b7e3SAndre Fischer 7089f91b7e3SAndre Fischer return ($file_count, $directory_count); 7099f91b7e3SAndre Fischer} 7109f91b7e3SAndre Fischer 7119f91b7e3SAndre Fischer 7129f91b7e3SAndre Fischer 7139f91b7e3SAndre Fischer 7149f91b7e3SAndre Fischersub CheckLocalCopy ($$$$) 7159f91b7e3SAndre Fischer{ 7169f91b7e3SAndre Fischer my ($version, $language, $package_format, $product_name) = @_; 7179f91b7e3SAndre Fischer 7189f91b7e3SAndre Fischer # Compare creation times of the original .msi and its copy. 7199f91b7e3SAndre Fischer 7209f91b7e3SAndre Fischer my $original_path = File::Spec->catfile( 7219f91b7e3SAndre Fischer $ENV{'SRC_ROOT'}, 7229f91b7e3SAndre Fischer "instsetoo_native", 7239f91b7e3SAndre Fischer $ENV{'INPATH'}, 7249f91b7e3SAndre Fischer $product_name, 7259f91b7e3SAndre Fischer $package_format, 7269f91b7e3SAndre Fischer "install", 7279f91b7e3SAndre Fischer $language); 7289f91b7e3SAndre Fischer 7299f91b7e3SAndre Fischer my $copy_path = installer::patch::InstallationSet::GetUnpackedExePath( 7309f91b7e3SAndre Fischer $version, 7319f91b7e3SAndre Fischer 1, 7329f91b7e3SAndre Fischer $language, 7339f91b7e3SAndre Fischer $package_format, 7349f91b7e3SAndre Fischer $product_name); 7359f91b7e3SAndre Fischer 7369f91b7e3SAndre Fischer my $msi_basename = "openoffice" 7379f91b7e3SAndre Fischer . installer::patch::Version::ArrayToNoDotName( 7389f91b7e3SAndre Fischer installer::patch::Version::StringToNumberArray($version)) 7399f91b7e3SAndre Fischer . ".msi"; 7409f91b7e3SAndre Fischer 7419f91b7e3SAndre Fischer my $original_msi_filename = File::Spec->catfile($original_path, $msi_basename); 7429f91b7e3SAndre Fischer my $copied_msi_filename = File::Spec->catfile($copy_path, $msi_basename); 7439f91b7e3SAndre Fischer 7449f91b7e3SAndre Fischer my @original_msi_stats = stat($original_msi_filename); 7459f91b7e3SAndre Fischer my @copied_msi_stats = stat($copied_msi_filename); 7469f91b7e3SAndre Fischer my $original_msi_mtime = $original_msi_stats[9]; 7479f91b7e3SAndre Fischer my $copied_msi_mtime = $copied_msi_stats[9]; 7489f91b7e3SAndre Fischer 7499f91b7e3SAndre Fischer if (defined $original_msi_mtime 7509f91b7e3SAndre Fischer && defined $copied_msi_mtime 7519f91b7e3SAndre Fischer && $original_msi_mtime > $copied_msi_mtime) 7529f91b7e3SAndre Fischer { 7539f91b7e3SAndre Fischer # The installation set is newer than its copy. 7549f91b7e3SAndre Fischer # Remove the copy. 7559f91b7e3SAndre Fischer $installer::logger::Info->printf( 7569f91b7e3SAndre Fischer "removing copy of installation set (version %s) because it is out of date\n", 7579f91b7e3SAndre Fischer $version); 7589f91b7e3SAndre Fischer File::Path::remove_tree($copy_path); 7599f91b7e3SAndre Fischer } 7609f91b7e3SAndre Fischer} 7619f91b7e3SAndre Fischer 7629f91b7e3SAndre Fischer 7639f91b7e3SAndre Fischer 7649f91b7e3SAndre Fischer 7659f91b7e3SAndre Fischer=head2 ProvideUnpackedCab 7669f91b7e3SAndre Fischer 7679f91b7e3SAndre Fischer 1a. Make sure that a downloadable installation set is present. 7689f91b7e3SAndre Fischer 1b. or that a freshly built installation set (packed and unpacked is present) 7699f91b7e3SAndre Fischer 2. Unpack the downloadable installation set 7709f91b7e3SAndre Fischer 3. Unpack the .cab file. 7719f91b7e3SAndre Fischer 7729f91b7e3SAndre Fischer The 'Provide' in the function name means that any step that has 7739f91b7e3SAndre Fischer already been made is not made again. 7749f91b7e3SAndre Fischer 7759f91b7e3SAndre Fischer=cut 7769f91b7e3SAndre Fischersub ProvideUnpackedCab ($$$$$) 7779f91b7e3SAndre Fischer{ 7789f91b7e3SAndre Fischer my ($version, $is_current_version, $language, $package_format, $product_name) = @_; 7799f91b7e3SAndre Fischer 7809f91b7e3SAndre Fischer if ($is_current_version) 7819f91b7e3SAndre Fischer { 7829f91b7e3SAndre Fischer # For creating patches we maintain a copy of the unpacked .exe. Make sure that that is updated when 7839f91b7e3SAndre Fischer # a new installation set has been built. 7849f91b7e3SAndre Fischer CheckLocalCopy($version, $language, $package_format, $product_name); 7859f91b7e3SAndre Fischer } 7869f91b7e3SAndre Fischer 7879f91b7e3SAndre Fischer # Check if the cab file has already been unpacked. 7889f91b7e3SAndre Fischer my $unpacked_cab_path = installer::patch::InstallationSet::GetUnpackedCabPath( 7899f91b7e3SAndre Fischer $version, 7909f91b7e3SAndre Fischer $is_current_version, 7919f91b7e3SAndre Fischer $language, 7929f91b7e3SAndre Fischer $package_format, 7939f91b7e3SAndre Fischer $product_name); 7949f91b7e3SAndre Fischer my $unpacked_cab_flag_filename = File::Spec->catfile($unpacked_cab_path, "__cab_is_unpacked"); 7959f91b7e3SAndre Fischer my $cab_is_unpacked = -f $unpacked_cab_flag_filename; 7969f91b7e3SAndre Fischer 7979f91b7e3SAndre Fischer if ($cab_is_unpacked) 7989f91b7e3SAndre Fischer { 7999f91b7e3SAndre Fischer # Yes. Cab was already unpacked. There is nothing more to do. 8009f91b7e3SAndre Fischer $installer::logger::Info->printf("cab has already been unpacked to\n"); 8019f91b7e3SAndre Fischer $installer::logger::Info->printf(" %s\n", $unpacked_cab_path); 8029f91b7e3SAndre Fischer 8039f91b7e3SAndre Fischer return 1; 8049f91b7e3SAndre Fischer } 8059f91b7e3SAndre Fischer else 8069f91b7e3SAndre Fischer { 8079f91b7e3SAndre Fischer # Make sure that the exe is unpacked and the cab file exists. 8089f91b7e3SAndre Fischer ProvideUnpackedExe($version, $is_current_version, $language, $package_format, $product_name); 8099f91b7e3SAndre Fischer 8109f91b7e3SAndre Fischer # Unpack the cab file. 8119f91b7e3SAndre Fischer my $unpacked_exe_path = installer::patch::InstallationSet::GetUnpackedExePath( 8129f91b7e3SAndre Fischer $version, 8139f91b7e3SAndre Fischer $is_current_version, 8149f91b7e3SAndre Fischer $language, 8159f91b7e3SAndre Fischer $package_format, 8169f91b7e3SAndre Fischer $product_name); 8179f91b7e3SAndre Fischer my $msi = new installer::patch::Msi( 8189f91b7e3SAndre Fischer installer::patch::InstallationSet::GetMsiFilename($unpacked_exe_path, $version), 8199f91b7e3SAndre Fischer $version, 8209f91b7e3SAndre Fischer $is_current_version, 8219f91b7e3SAndre Fischer $language, 8229f91b7e3SAndre Fischer $product_name); 8239f91b7e3SAndre Fischer 8249f91b7e3SAndre Fischer my $cab_filename = installer::patch::InstallationSet::GetCabFilename( 8259f91b7e3SAndre Fischer $unpacked_exe_path, 8269f91b7e3SAndre Fischer $version); 8279f91b7e3SAndre Fischer if ( ! -f $cab_filename) 8289f91b7e3SAndre Fischer { 8299f91b7e3SAndre Fischer # Cab file does not exist. 8309f91b7e3SAndre Fischer installer::logger::PrintError( 8319f91b7e3SAndre Fischer "could not find .cab file at '%s'. Extraction of .exe seems to have failed.\n", 8329f91b7e3SAndre Fischer $cab_filename); 8339f91b7e3SAndre Fischer return 0; 8349f91b7e3SAndre Fischer } 8359f91b7e3SAndre Fischer 8369f91b7e3SAndre Fischer if (installer::patch::InstallationSet::UnpackCab( 8379f91b7e3SAndre Fischer $cab_filename, 8389f91b7e3SAndre Fischer $msi, 8399f91b7e3SAndre Fischer $unpacked_cab_path)) 8409f91b7e3SAndre Fischer { 8419f91b7e3SAndre Fischer $installer::logger::Info->printf("unpacked cab file '%s'\n", $cab_filename); 8429f91b7e3SAndre Fischer $installer::logger::Info->printf(" to '%s'\n", $unpacked_cab_path); 8439f91b7e3SAndre Fischer 844*677600b0SAndre Fischer installer::patch::Tools::touch($unpacked_cab_flag_filename); 8459f91b7e3SAndre Fischer 8469f91b7e3SAndre Fischer return 1; 8479f91b7e3SAndre Fischer } 8489f91b7e3SAndre Fischer else 8499f91b7e3SAndre Fischer { 8509f91b7e3SAndre Fischer return 0; 8519f91b7e3SAndre Fischer } 8529f91b7e3SAndre Fischer } 8539f91b7e3SAndre Fischer} 854c9b362f6SAndre Fischer1; 855