[Libreoffice-commits] core.git: Branch 'aoo/trunk' - 5 commits - instsetoo_native/data instsetoo_native/util scp2/source setup_native/source solenv/bin
Andre Fischer
af at apache.org
Tue Nov 12 06:08:47 PST 2013
instsetoo_native/data/releases.xml | 316 +++
instsetoo_native/util/openoffice.lst | 2
scp2/source/ooo/mergemodules_ooo.scp | 52
setup_native/source/packinfo/finals_instsetoo.txt | 35
solenv/bin/make_installer.pl | 58
solenv/bin/modules/installer/globals.pm | 14
solenv/bin/modules/installer/patch/FileOperations.pm | 333 +++
solenv/bin/modules/installer/patch/FileSequenceList.pm | 159 +
solenv/bin/modules/installer/patch/InstallationSet.pm | 467 ++++
solenv/bin/modules/installer/patch/Msi.pm | 342 +++
solenv/bin/modules/installer/patch/MsiRow.pm | 160 +
solenv/bin/modules/installer/patch/MsiTable.pm | 274 ++
solenv/bin/modules/installer/patch/ReleasesList.pm | 210 ++
solenv/bin/modules/installer/patch/Tools.pm | 47
solenv/bin/modules/installer/patch/Version.pm | 74
solenv/bin/modules/installer/windows/component.pm | 5
solenv/bin/modules/installer/windows/directory.pm | 9
solenv/bin/modules/installer/windows/file.pm | 193 -
solenv/bin/modules/installer/windows/media.pm | 106 -
solenv/bin/modules/installer/windows/mergemodule.pm | 1668 -----------------
solenv/bin/modules/installer/windows/msiglobal.pm | 279 --
solenv/bin/modules/installer/windows/msp.pm | 1493 ---------------
solenv/bin/modules/installer/windows/update.pm | 595 ------
solenv/bin/modules/par2script/globals.pm | 3
solenv/bin/modules/pre2par/globals.pm | 3
solenv/bin/patch_make_releases_xml.pl | 197 ++
solenv/bin/release_prepare.pl | 226 ++
27 files changed, 2820 insertions(+), 4500 deletions(-)
New commits:
commit 1a43068abda6e8f4eb006d5adb18dc0793e513c9
Author: Andre Fischer <af at apache.org>
Date: Tue Nov 12 13:49:49 2013 +0000
123531: Added some new files (scripts and modules) for creating patches.
diff --git a/instsetoo_native/data/releases.xml b/instsetoo_native/data/releases.xml
new file mode 100644
index 0000000..34c4d07
--- /dev/null
+++ b/instsetoo_native/data/releases.xml
@@ -0,0 +1,316 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--***********************************************************
+ *
+ * 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.
+ *
+ ***********************************************************-->
+<releases>
+ <release>
+ <version>4.0.0</version>
+ <download>
+ <package-format>msi</package-format>
+ <url-template>
+ http://archive.apache.org/dist/openoffice/4.0.0/binaries/%L/Apache_OpenOffice_4.0.0_Win_x86_install_%L.exe
+ </url-template>
+ <item>
+ <language>ast</language>
+ <checksum type="sha256">415e2f3cf4d99a3f6ad495e33b89c716ef6966c9c4d7df90ad6e004fcf0222f4</checksum>
+ <size>154219869</size>
+ </item>
+ <item>
+ <language>cs</language>
+ <checksum type="sha256">a90a2c00c58f3e30654b89b4a363b099b0a7d1f829ebf9c7c18333d387f4bf41</checksum>
+ <size>130773239</size>
+ </item>
+ <item>
+ <language>de</language>
+ <checksum type="sha256">5569634ac40b42a710c666d0511f6aa4dbcb05d1a525e06f6be038e828c507f0</checksum>
+ <size>162401424</size>
+ </item>
+ <item>
+ <language>el</language>
+ <checksum type="sha256">cc5cde6314cea634200da6861da527c11ca7d74338074cdd4e5a22e1ffd9ef7c</checksum>
+ <size>139633387</size>
+ </item>
+ <item>
+ <language>en-GB</language>
+ <checksum type="sha256">7f83397877b72e7f2da38f11b76c3f46e30b93713b40becba699d21f913847e0</checksum>
+ <size>136201626</size>
+ </item>
+ <item>
+ <language>en-US</language>
+ <checksum type="sha256">8db246183f549c298d731cf61771f8f8adb37028d8ecc737fe1ad452899adb2d</checksum>
+ <size>143436858</size>
+ </item>
+ <item>
+ <language>es</language>
+ <checksum type="sha256">eb991c71b436c4d740f3d2b5441716fc321bb57eb7f36c7019ec86feebb7f5d4</checksum>
+ <size>132424454</size>
+ </item>
+ <item>
+ <language>fi</language>
+ <checksum type="sha256">fa2b9015864651be44afc940988ed20c6093bc8707aea72ab1b75cf147d81ed2</checksum>
+ <size>138474963</size>
+ </item>
+ <item>
+ <language>fr</language>
+ <checksum type="sha256">b4b20eac7f6220a4a6250e79d950a328d08b927b8856d762b0b1e033833e198f</checksum>
+ <size>133397214</size>
+ </item>
+ <item>
+ <language>gd</language>
+ <checksum type="sha256">c2e5ac75f899efab61f039a193a68ec2f4d092fd43c6eb46d8b2d34d8166ce6e</checksum>
+ <size>154472734</size>
+ </item>
+ <item>
+ <language>gl</language>
+ <checksum type="sha256">bac4915fd47b9e219d72a02a268fa590096c0884ebafd966b10e9b77fe16eee0</checksum>
+ <size>137952793</size>
+ </item>
+ <item>
+ <language>hu</language>
+ <checksum type="sha256">2e01d00431692cb6071cf520e71b900dba28a846dccf4ed3a85c245761c98906</checksum>
+ <size>133240224</size>
+ </item>
+ <item>
+ <language>it</language>
+ <checksum type="sha256">8663c01de8f62b26a7864ac4da6abd316a1c2e00b35c60372cad5287120fe409</checksum>
+ <size>138823014</size>
+ </item>
+ <item>
+ <language>ja</language>
+ <checksum type="sha256">559f165ee9ff516a80573befaf7d0936ca81fa89aca655213b4f265eb7c7059a</checksum>
+ <size>136416679</size>
+ </item>
+ <item>
+ <language>ko</language>
+ <checksum type="sha256">daa7f3b51e6ffb0b541a98fbcdc0bad53eea579a7d74c9acbdd73ad660b117b1</checksum>
+ <size>131617051</size>
+ </item>
+ <item>
+ <language>nl</language>
+ <checksum type="sha256">fcc6e55c7a1407be8e8f2faf7305ebb9a8f7e1bea882e5d917b5846a2c0ee955</checksum>
+ <size>138526756</size>
+ </item>
+ <item>
+ <language>pt</language>
+ <checksum type="sha256">58307e0eeb485840e1462a23f8741e793422ccdc468123f85876ae287482a987</checksum>
+ <size>130929247</size>
+ </item>
+ <item>
+ <language>pt-BR</language>
+ <checksum type="sha256">08ef83f28e138dc0bc6bdf761e4676eb13c2b30717ce47e0becec2de90c73f7a</checksum>
+ <size>130814647</size>
+ </item>
+ <item>
+ <language>ru</language>
+ <checksum type="sha256">dda689b273eb9ddadfb156a08df8e73c3b41e3cc8178a16546e282f8e1c54d77</checksum>
+ <size>137558077</size>
+ </item>
+ <item>
+ <language>sk</language>
+ <checksum type="sha256">d2722d2569178838a57705e76062603f995f71d5219e8f910bc7a6b46fa6039a</checksum>
+ <size>131199460</size>
+ </item>
+ <item>
+ <language>sl</language>
+ <checksum type="sha256">eecea1c75833a873a3cc00f81c85f411319b085728224c716ac90159622c0c3e</checksum>
+ <size>132340393</size>
+ </item>
+ <item>
+ <language>ta</language>
+ <checksum type="sha256">4051b4831a960a8f27a3f56f32d7bd5a7bbdfcf859238a149aca9cd69ae0121c</checksum>
+ <size>136961005</size>
+ </item>
+ <item>
+ <language>zh-CN</language>
+ <checksum type="sha256">94424b9c24d3237e70d6452da8366cf9c6617a46fa171901db093b1a1166934d</checksum>
+ <size>131840961</size>
+ </item>
+ </download>
+ </release>
+ <release>
+ <version>4.0.1</version>
+ <download>
+ <package-format>msi</package-format>
+ <url-template>
+ http://archive.apache.org/dist/openoffice/4.0.1/binaries/%L/Apache_OpenOffice_4.0.1_Win_x86_install_%L.exe
+ </url-template>
+ <item>
+ <language>ast</language>
+ <checksum type="sha256">9854b6a99c6e56902e30ec01009e294aafe091e4733e9b8933690ee0365d6754</checksum>
+ <size>154320289</size>
+ </item>
+ <item>
+ <language>cs</language>
+ <checksum type="sha256">b23c5dc07a6e521a7ad24e7c1d131c96ea3a6fdf3a2f96020b5cad2e7ebe0253</checksum>
+ <size>130785256</size>
+ </item>
+ <item>
+ <language>de</language>
+ <checksum type="sha256">fbbe39def767e6ecd16c7b6802f35d6e4b035c4b72328bbf0a8f045cf585aaa7</checksum>
+ <size>163606685</size>
+ </item>
+ <item>
+ <language>el</language>
+ <checksum type="sha256">e59f47b986c4bcd8f21062446b299f68ac7ed941356813b0e2dbd651fb59c847</checksum>
+ <size>139717373</size>
+ </item>
+ <item>
+ <language>en-GB</language>
+ <checksum type="sha256">75f06dbe9f13804ea9f3ef20d831e300a55df1bf1a5b656d2422206a8a0d8bda</checksum>
+ <size>136295104</size>
+ </item>
+ <item>
+ <language>en-US</language>
+ <checksum type="sha256">3b68145a33fa83d246febb3b7551fb0cbf57363bc772401ac0c37cfc1cde21b3</checksum>
+ <size>143485940</size>
+ </item>
+ <item>
+ <language>es</language>
+ <checksum type="sha256">5136276a370378d11327b9a0bd074d269a49e797c7186f2e3cc9cf6c0bbc20fc</checksum>
+ <size>132478227</size>
+ </item>
+ <item>
+ <language>eu</language>
+ <checksum type="sha256">aae1ff61af9ac117637842ccc1c28221620c79b05ffbb1fb47d8a6fcbe3b1700</checksum>
+ <size>131476228</size>
+ </item>
+ <item>
+ <language>fi</language>
+ <checksum type="sha256">65ff3209a51afefde11dd1326921340ebe035f09626d8884f37a0f72f8c2785b</checksum>
+ <size>138523539</size>
+ </item>
+ <item>
+ <language>fr</language>
+ <checksum type="sha256">70c97dc59412a8e4aeb87e51e8714cbba776397beb6a774804591653150e78d5</checksum>
+ <size>134622711</size>
+ </item>
+ <item>
+ <language>gd</language>
+ <checksum type="sha256">a57115a636f4004de2df9599e72bc4d07937b65a6bb99fe126dc18a788a57142</checksum>
+ <size>154574682</size>
+ </item>
+ <item>
+ <language>gl</language>
+ <checksum type="sha256">4c8fe9b42193dc37dc6a2b979b790ea6317ea25a6fa27fcb9007036c5725111d</checksum>
+ <size>138019151</size>
+ </item>
+ <item>
+ <language>hu</language>
+ <checksum type="sha256">97765ef536ed1e3f07220fe4cb90520efdfb376fab751ad2cac7390316f14e65</checksum>
+ <size>133302800</size>
+ </item>
+ <item>
+ <language>it</language>
+ <checksum type="sha256">c6fa3e0e9bef615d804b5d24d3f2cc49f7655aee01ef34cecb9b520a47249d02</checksum>
+ <size>138894766</size>
+ </item>
+ <item>
+ <language>ja</language>
+ <checksum type="sha256">93d20ae5f96f4a93c705894849f01b6501604bf003e9b66f7d0dbdc6f2282965</checksum>
+ <size>136444096</size>
+ </item>
+ <item>
+ <language>km</language>
+ <checksum type="sha256">4fc263c631d4ba797633d28ca529202b600d5fe676a8c215904d12d08ed8cc49</checksum>
+ <size>151866955</size>
+ </item>
+ <item>
+ <language>ko</language>
+ <checksum type="sha256">2abd13afe2978c4300d872a06dcec00ae23592ed563be3d0d046ef81738d7a87</checksum>
+ <size>131671507</size>
+ </item>
+ <item>
+ <language>lt</language>
+ <checksum type="sha256">4ac6c2c88edb5254e0cf93f49daaf5e411ea0168d6c431d11da5d89638977cff</checksum>
+ <size>136935582</size>
+ </item>
+ <item>
+ <language>nl</language>
+ <checksum type="sha256">85292dad5aa80711c126091d3565dc9cd2219d818a59cbd5c7c9a4bc5282ebb8</checksum>
+ <size>139734741</size>
+ </item>
+ <item>
+ <language>pl</language>
+ <checksum type="sha256">c71c63d0c0e76f28b7d3bebb39e1cb9c0ca35e29557c53528f631e6c1aeca04c</checksum>
+ <size>133661993</size>
+ </item>
+ <item>
+ <language>pt-BR</language>
+ <checksum type="sha256">e6baed3d30d4b18e32e21ab4fcd22446ac1f8a40efe49a4f105e9c3fc0ba1611</checksum>
+ <size>130866989</size>
+ </item>
+ <item>
+ <language>pt</language>
+ <checksum type="sha256">dd855dc99fc41fd509e938881397798fa2e9ed92e663cb8b9ea6c356d5d5a096</checksum>
+ <size>130989882</size>
+ </item>
+ <item>
+ <language>ru</language>
+ <checksum type="sha256">7e965822f8dfb0aa4a67bf5bff8ddb852901c672886bb9f2ee275c5c976c0a48</checksum>
+ <size>137584051</size>
+ </item>
+ <item>
+ <language>sk</language>
+ <checksum type="sha256">4400eb30ca5072b175da7963049bb0ecca761af73b7dbccb9a0b4cd789b26042</checksum>
+ <size>131265676</size>
+ </item>
+ <item>
+ <language>sl</language>
+ <checksum type="sha256">83d384d9e50ddcb9c1d74069d8796e5f37bed55b5da6f43c326c0784a6e61cef</checksum>
+ <size>132368586</size>
+ </item>
+ <item>
+ <language>sr</language>
+ <checksum type="sha256">a2d2e043c1c3fa9a90924ae29138641b238d7749984f873a8672e2844a55e3d9</checksum>
+ <size>136961170</size>
+ </item>
+ <item>
+ <language>sv</language>
+ <checksum type="sha256">15cbdb4f5a7ecf253f31981d0203c08e279a26603ca737e64f740524e1d672ca</checksum>
+ <size>131330363</size>
+ </item>
+ <item>
+ <language>ta</language>
+ <checksum type="sha256">352083d6d2fc6c39027a03fbbb6449d4a67955b370c5a8efba0407b74a456bc9</checksum>
+ <size>137001517</size>
+ </item>
+ <item>
+ <language>tr</language>
+ <checksum type="sha256">bdfbf83cc905bf44f086ea51295899a042667fa6334e6378ef5b5b354843ba37</checksum>
+ <size>130397087</size>
+ </item>
+ <item>
+ <language>vi</language>
+ <checksum type="sha256">0483c20036f47738ae86a19d0ab4e66eff8d8f5226f716970a4ec7f56a78bff6</checksum>
+ <size>131526617</size>
+ </item>
+ <item>
+ <language>zh-CN</language>
+ <checksum type="sha256">f2966f3c251cf31a24d7931950838c04e410935dd15a6fdd9241acf81bc5e784</checksum>
+ <size>131863915</size>
+ </item>
+ <item>
+ <language>zh-TW</language>
+ <checksum type="sha256">a194cfb2dc2cbcae2e89740485ebfcbf605b7c80a5bbdffb699e447c53698e53</checksum>
+ <size>131990994</size>
+ </item>
+ </download>
+ </release>
+</releases>
\ No newline at end of file
diff --git a/solenv/bin/modules/installer/patch/FileOperations.pm b/solenv/bin/modules/installer/patch/FileOperations.pm
new file mode 100644
index 0000000..931db2e
--- /dev/null
+++ b/solenv/bin/modules/installer/patch/FileOperations.pm
@@ -0,0 +1,333 @@
+#**************************************************************
+#
+# 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::FileOperations;
+
+use File::Basename;
+use File::Copy;
+use IO::Compress::Bzip2;
+use IO::Uncompress::Bunzip2;
+
+my $CompressionMethod = "bzip2";
+
+
+=head1 NAME
+
+ package installer::patch::FileOperations - Class for collecting, checking and executing file operations.
+
+=cut
+
+
+sub new ($)
+{
+ my ($class) = (@_);
+
+ my $self = {
+ 'operations' => []
+ };
+ bless($self, $class);
+
+ return $self;
+}
+
+
+
+
+sub AddCopyOperation ($$$)
+{
+ my ($self, $source_name, $target_name) = @_;
+
+ push
+ @{$self->{'operations'}},
+ [
+ 'copy',
+ $source_name,
+ $target_name
+ ];
+}
+
+
+
+
+sub AddMakeDirectoryOperation ($$)
+{
+ my ($self, $path) = @_;
+
+ push
+ @{$self->{'operations'}},
+ [
+ 'mkdir',
+ $path
+ ];
+}
+
+
+
+
+sub AddCompressOperation ($$)
+{
+ my ($self, $filename) = @_;
+
+ push
+ @{$self->{'operations'}},
+ [
+ 'compress',
+ $filename
+ ];
+}
+
+
+
+
+sub AddUncompressOperation ($$$)
+{
+ my ($self, $source_name, $target_name) = @_;
+
+ push
+ @{$self->{'operations'}},
+ [
+ 'uncompress',
+ $source_name,
+ $target_name
+ ];
+}
+
+
+
+
+sub Check ($)
+{
+ my ($self) = @_;
+
+ # Keep track of which directories or files would be created to check if
+ # operations that depend on these files will succeed.
+ my %files = ();
+ my %directories = ();
+
+ my @error_messages = ();
+ foreach my $operation (@{$self->{'operations'}})
+ {
+ my $command = $operation->[0];
+
+ if ($command eq "copy")
+ {
+ my ($source_name, $destination_name) = ($operation->[1], $operation->[2]);
+ if ( ! -f $source_name)
+ {
+ push @error_messages, sprintf("%s is not a regular file and can not be copied", $source_name);
+ }
+ my $destination_path = dirname($destination_name);
+ if ( ! -d $destination_path && ! defined $directories{$destination_path})
+ {
+ push @error_messages, sprintf("destination path %s does not exist", $destination_path);
+ }
+ if ( -f $destination_name)
+ {
+ # The destination file already exists. We have to overwrite it.
+ if ( ! -w $destination_name)
+ {
+ push @error_messges, sprintf("destination file %s exists but can not be overwritten", $destination_name);
+ }
+ }
+ $files{$destination_name} = 1;
+ }
+ elsif ($command eq "mkdir")
+ {
+ my $path = $operation->[1];
+ if ( -d $path)
+ {
+ # Directory already exists. That is OK, the mkdir command will be silently ignored.
+ }
+ else
+ {
+ $directories{$path} = 1;
+ }
+ }
+ elsif ($command eq "compress")
+ {
+ my $filename = $operation->[1];
+ if ( ! -f $filename && ! defined $files{$filename})
+ {
+ # File does not exist and will not be created by an earlier operation.
+ push @error_messages, sprintf("file %s does not exist and can not be compressed", $filename);
+ }
+ }
+ elsif ($command eq "uncompress")
+ {
+ my ($source_filename, $destination_filename) = ($operation->[1], $operation->[2]);
+ if ($CompressionMethod eq "bzip2")
+ {
+ $source_filename .= ".bz2";
+ }
+ if ( ! -f $source_filename && ! defined $files{$source_filename})
+ {
+ # File does not exist and will not be created by an earlier operation.
+ push @error_messages, sprintf("file %s does not exist and can not be decompressed", $source_filename);
+ }
+ if ( -f $destination_filename && ! -w $destination_filename)
+ {
+ # Destination file aleady exists but can not be replaced.
+ push @error_messages, sprintf("compress destination file %s exists but can not be replaced", $destination_filename);
+ }
+ }
+ else
+ {
+ push @error_messages, sprintf("unknown operation %s", $command);
+ }
+ }
+
+ return @error_messages;
+}
+
+
+
+
+sub CheckAndExecute ($)
+{
+ my ($self) = @_;
+
+ my @error_messages = $self->Check();
+ if (scalar @error_messages > 0)
+ {
+ $installer::logger::Lang->printf("can not execute all operations:\n");
+ for my $message (@error_messages)
+ {
+ $installer::logger::Lang->printf("ERROR: %s\n", $message);
+ }
+ return 0;
+ }
+ else
+ {
+ return $self->Execute();
+ }
+}
+
+
+
+
+sub Execute ($)
+{
+ my ($self) = @_;
+
+ foreach my $operation (@{$self->{'operations'}})
+ {
+ my $command = $operation->[0];
+
+ if ($command eq "copy")
+ {
+ my ($source_name, $destination_name) = ($operation->[1], $operation->[2]);
+ $installer::logger::Lang->printf("copy from %s\n to %s\n", $source_name, $destination_name);
+ if ( ! $DryRun)
+ {
+ my $result = copy($source_name, $destination_name);
+ if ( ! $result)
+ {
+ $installer::logger::Lang->printf("ERROR: copying from %s to %s failed",
+ $source_name, $destination_name);
+ }
+ }
+ }
+ elsif ($command eq "mkdir")
+ {
+ my $path = $operation->[1];
+ if ( -d $path)
+ {
+ # Path exists already. Do nothing.
+ }
+ else
+ {
+ $installer::logger::Lang->printf("creating directory %s\n", $path);
+ if ( ! $DryRun)
+ {
+ if (File::Path::make_path($path, {'mode' => 0775}) == 0)
+ {
+ $installer::logger::Lang->printf("could not create directory %s\n", $path);
+ }
+ }
+ }
+ }
+ elsif ($command eq "compress")
+ {
+ my $filename = $operation->[1];
+ $installer::logger::Lang->printf("compressing %s\n", $filename);
+ if ( ! $DryRun)
+ {
+ my $result = 0;
+ if ($CompressionMethod eq "bzip2")
+ {
+ $result = IO::Compress::Bzip2::bzip2($filename => $filename.".bz2");
+ }
+ if ($result == 0)
+ {
+ $installer::logger::Lang->printf("ERROR: could not compress %s\n", $filename);
+ }
+ else
+ {
+ unlink($filename);
+ }
+ }
+ }
+ elsif ($command eq "uncompress")
+ {
+ my ($source_name, $destination_name) = ($operation->[1], $operation->[2]);
+ if ($CompressionMethod eq "bzip2")
+ {
+ $source_name .= ".bz2";
+ }
+ $installer::logger::Lang->printf("uncompressing %s to %s\n", $source_name, $destination_name);
+
+ my $destination_base_name = basename($destination_name);
+
+ if ( ! $DryRun)
+ {
+ my $result = 0;
+ if ($CompressionMethod eq "bzip2")
+ {
+ $result = IO::Uncompress::Bunzip2::bunzip2($source_name => $destination_name);
+ }
+ if ($result == 0)
+ {
+ $installer::logger::Lang->printf("ERROR: failed to extract content of '%s' from '%s'\n",
+ $destination_name, $source_name);
+ return 0;
+ }
+ }
+ }
+
+ else
+ {
+ die "unknown operation $command\n";
+ }
+ }
+
+ return 1;
+}
+
+
+
+sub GetOperationCount ($)
+{
+ my ($self) = @_;
+ return scalar @{$self->{'operations'}};
+}
+
+
+1;
diff --git a/solenv/bin/modules/installer/patch/FileSequenceList.pm b/solenv/bin/modules/installer/patch/FileSequenceList.pm
new file mode 100644
index 0000000..6c607d8
--- /dev/null
+++ b/solenv/bin/modules/installer/patch/FileSequenceList.pm
@@ -0,0 +1,159 @@
+#**************************************************************
+#
+# 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;
diff --git a/solenv/bin/modules/installer/patch/InstallationSet.pm b/solenv/bin/modules/installer/patch/InstallationSet.pm
new file mode 100644
index 0000000..67ff1fe
--- /dev/null
+++ b/solenv/bin/modules/installer/patch/InstallationSet.pm
@@ -0,0 +1,467 @@
+#**************************************************************
+#
+# 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;
diff --git a/solenv/bin/modules/installer/patch/Msi.pm b/solenv/bin/modules/installer/patch/Msi.pm
new file mode 100644
index 0000000..c5c650a
--- /dev/null
+++ b/solenv/bin/modules/installer/patch/Msi.pm
@@ -0,0 +1,342 @@
+#**************************************************************
+#
+# 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::Msi;
+
+use installer::patch::MsiTable;
+use installer::patch::Tools;
+use strict;
+
+
+=head1 NAME
+
+ package installer::patch::Msi - Class represents a single MSI file and gives access to its tables.
+
+=cut
+
+
+
+=head2 new($class, $version, $language, $product_name)
+
+ Create a new object of the Msi class. The values of $version, $language, and $product_name define
+ where to look for the msi file.
+
+ If construction fails then IsValid() will return false.
+
+=cut
+sub new ($$$$)
+{
+ my ($class, $version, $language, $product_name) = @_;
+
+ my $path = installer::patch::InstallationSet::GetUnpackedMsiPath(
+ $version,
+ $language,
+ "msi",
+ $product_name);
+
+ # Find the msi in the path.
+ my $filename = undef;
+ if ( -d $path)
+ {
+ my @msi_files = glob(File::Spec->catfile($path, "*.msi"));
+ if (scalar @msi_files != 1)
+ {
+ printf STDERR ("there are %d msi files in %s, should be 1", scalar @msi_files, $filename);
+ $filename = "";
+ }
+ else
+ {
+ $filename = $msi_files[0];
+ }
+ }
+ else
+ {
+ installer::logger::PrintError("can not access path '%s' to find msi\n", $path);
+ return undef;
+ }
+
+ if ( ! -f $filename)
+ {
+ installer::logger::PrintError("can not access MSI file at '%s'\n", $filename);
+ return undef;
+ }
+
+ my $self = {
+ 'filename' => $filename,
+ 'path' => $path,
+ 'version' => $version,
+ 'language' => $language,
+ 'package_format' => "msi",
+ 'product_name' => $product_name,
+ 'tmpdir' => File::Temp->newdir(CLEANUP => 1),
+ 'is_valid' => -f $filename
+ };
+ bless($self, $class);
+
+ return $self;
+}
+
+
+
+
+sub IsValid ($)
+{
+ my ($self) = @_;
+
+ return $self->{'is_valid'};
+}
+
+
+
+
+=head2 GetTable($seld, $table_name)
+
+ Return an MsiTable object for $table_name. Table objects are kept
+ alive for the life time of the Msi object. Therefore the second
+ call for the same table is very cheap.
+
+=cut
+sub GetTable ($$)
+{
+ my ($self, $table_name) = @_;
+
+ my $table = $self->{'tables'}->{$table_name};
+ if ( ! defined $table)
+ {
+ my $table_filename = File::Spec->catfile($self->{'tmpdir'}, $table_name .".idt");
+ if ( ! -f $table_filename
+ || ! EnsureAYoungerThanB($table_filename, $self->{'fullname'}))
+ {
+ # Extract table from database to text file on disk.
+ my $truncated_table_name = length($table_name)>8 ? substr($table_name,0,8) : $table_name;
+ my $command = join(" ",
+ "msidb.exe",
+ "-d", installer::patch::Tools::CygpathToWindows($self->{'filename'}),
+ "-f", installer::patch::Tools::CygpathToWindows($self->{'tmpdir'}),
+ "-e", $table_name);
+ my $result = qx($command);
+ print $result;
+ }
+
+ # Read table into memory.
+ $table = new installer::patch::MsiTable($table_filename, $table_name);
+ $self->{'tables'}->{$table_name} = $table;
+ }
+
+ return $table;
+}
+
+
+
+
+=head2 EnsureAYoungerThanB ($filename_a, $filename_b)
+
+ Internal function (not a method) that compares to files according
+ to their last modification times (mtime).
+
+=cut
+sub EnsureAYoungerThanB ($$)
+{
+ my ($filename_a, $filename_b) = @_;
+
+ die("file $filename_a does not exist") unless -f $filename_a;
+ die("file $filename_b does not exist") unless -f $filename_b;
+
+ my @stat_a = stat($filename_a);
+ my @stat_b = stat($filename_b);
+
+ if ($stat_a[9] <= $stat_b[9])
+ {
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+
+
+
+=head2 SplitLongShortName($name)
+
+ Split $name (typically from the 'FileName' column in the 'File'
+ table or 'DefaultDir' column in the 'Directory' table) at the '|'
+ into short (8.3) and long names. If there is no '|' in $name then
+ $name is returned as both short and long name.
+
+ Returns long and short name (in this order) as array.
+
+=cut
+sub SplitLongShortName ($)
+{
+ my ($name) = @_;
+
+ if ($name =~ /^([^\|]*)\|(.*)$/)
+ {
+ return ($2,$1);
+ }
+ else
+ {
+ return ($name,$name);
+ }
+}
+
+
+
+=head2 SplitTargetSourceLongShortName ($name)
+
+ Split $name first at the ':' into target and source parts and each
+ of those at the '|'s into long and short parts. Names that follow
+ this pattern come from the 'DefaultDir' column in the 'Directory'
+ table.
+
+=cut
+sub SplitTargetSourceLongShortName ($)
+{
+ my ($name) = @_;
+
+ if ($name =~ /^([^:]*):(.*)$/)
+ {
+ return (installer::patch::Msi::SplitLongShortName($1), installer::patch::Msi::SplitLongShortName($2));
+ }
+ else
+ {
+ my ($long,$short) = installer::patch::Msi::SplitLongShortName($name);
+ return ($long,$short,$long,$short);
+ }
+}
+
+
+
+
+=head2 GetFileToDirectoryMap ($)
+
+ Return a map (hash) that maps the unique name (column 'File' in
+ the 'File' table) to its directory names. Each value is a
+ reference to an array of two elements: the source path and the
+ target path.
+
+ The map is kept alive for the lifetime of the Msi object. All
+ calls but the first are cheap.
+
+=cut
+sub GetFileToDirectoryMap ($)
+{
+ my ($self) = @_;
+
+ if (defined $self->{'FileToDirectoryMap'})
+ {
+ return $self->{'FileToDirectoryMap'};
+ }
+
+ my $file_table = $self->GetTable("File");
+ my $directory_table = $self->GetTable("Directory");
+ my $component_table = $self->GetTable("Component");
+ $installer::logger::Info->printf("got access to tables File, Directory, Component\n");
+
+ my %dir_map = ();
+ foreach my $row (@{$directory_table->GetAllRows()})
+ {
+ my ($target_name, undef, $source_name, undef)
+ = installer::patch::Msi::SplitTargetSourceLongShortName($row->GetValue("DefaultDir"));
+ $dir_map{$row->GetValue("Directory")} = {
+ 'parent' => $row->GetValue("Directory_Parent"),
+ 'source_name' => $source_name,
+ 'target_name' => $target_name};
+ }
+
+ # Set up full names for all directories.
+ my @todo = map {$_} (keys %dir_map);
+ my $process_count = 0;
+ my $push_count = 0;
+ while (scalar @todo > 0)
+ {
+ ++$process_count;
+
+ my $key = shift @todo;
+ my $item = $dir_map{$key};
+ next if defined $item->{'full_source_name'};
+
+ if ($item->{'parent'} eq "")
+ {
+ # Directory has no parent => full names are the same as the name.
+ $item->{'full_source_name'} = $item->{'source_name'};
+ $item->{'full_target_name'} = $item->{'target_name'};
+ }
+ else
+ {
+ my $parent = $dir_map{$item->{'parent'}};
+ if ( defined $parent->{'full_source_name'})
+ {
+ # Parent aleady has full names => we can create the full name of the current item.
+ $item->{'full_source_name'} = $parent->{'full_source_name'} . "/" . $item->{'source_name'};
+ $item->{'full_target_name'} = $parent->{'full_target_name'} . "/" . $item->{'target_name'};
+ }
+ else
+ {
+ # Parent has to be processed before the current item can be processed.
+ # Push both to the head of the list.
+ unshift @todo, $key;
+ unshift @todo, $item->{'parent'};
+
+ ++$push_count;
+ }
+ }
+ }
+
+ foreach my $key (keys %dir_map)
+ {
+ $dir_map{$key}->{'full_source_name'} =~ s/\/(\.\/)+/\//g;
+ $dir_map{$key}->{'full_source_name'} =~ s/^SourceDir\///;
+ $dir_map{$key}->{'full_target_name'} =~ s/\/(\.\/)+/\//g;
+ $dir_map{$key}->{'full_target_name'} =~ s/^SourceDir\///;
+ }
+ $installer::logger::Info->printf("for %d directories there where %d processing steps and %d pushes\n",
+ $directory_table->GetRowCount(),
+ $process_count,
+ $push_count);
+
+ # Setup a map from component names to directory items.
+ my %component_to_directory_map = map {$_->GetValue('Component') => $_->GetValue('Directory_')} @{$component_table->GetAllRows()};
+
+ # Finally, create the map from files to directories.
+ my $map = {};
+ my $file_component_index = $file_table->GetColumnIndex("Component_");
+ my $file_file_index = $file_table->GetColumnIndex("File");
+ foreach my $file_row (@{$file_table->GetAllRows()})
+ {
+ my $component_name = $file_row->GetValue($file_component_index);
+ my $directory_name = $component_to_directory_map{$component_name};
+ my $dir_item = $dir_map{$directory_name};
+ my $unique_name = $file_row->GetValue($file_file_index);
+ $map->{$unique_name} = [$dir_item->{'full_source_name'},$dir_item->{'full_target_name'}];
+ }
+
+ $installer::logger::Info->printf("got full paths for %d files\n",
+ $file_table->GetRowCount());
+
+ $self->{'FileToDirectoryMap'} = $map;
+ return $map;
+}
+
+
+1;
diff --git a/solenv/bin/modules/installer/patch/MsiRow.pm b/solenv/bin/modules/installer/patch/MsiRow.pm
new file mode 100644
index 0000000..24a6fd2
--- /dev/null
+++ b/solenv/bin/modules/installer/patch/MsiRow.pm
@@ -0,0 +1,160 @@
+#**************************************************************
+#
+# 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::MsiRow;
+
+=head1 NAME
+
+ package installer::patch::MsiRow - Class that represents a single row of an Msi table.
+
+=cut
+
+
+=head2 new ($class, $table, @data)
+
+ Create a new MsiRow object for the given table row data. Each row
+ stores a reference to its $table so that it can access global
+ values like column names.
+
+=cut
+sub new ($$@)
+{
+ my ($class, $table, @data) = @_;
+
+ my $self = {
+ 'table' => $table,
+ 'values' => [@data]
+ };
+ bless($self, $class);
+
+ my $column_count = $table->GetColumnCount();
+ while (scalar @{$self->{'values'}} < $column_count)
+ {
+ push @{$self->{'values'}}, "";
+ }
+
+ return $self;
+}
+
+
+
+=head2 GetValue($self, $column)
+
+ Return the value in the column specified by $column, which can be
+ either the column name or the index of the column.
+
+=cut
+sub GetValue ($$)
+{
+ my ($self, $column) = @_;
+
+ if ($column =~ /^\d+$/)
+ {
+ return $self->{'values'}->[$column];
+ }
+ else
+ {
+ my $column_index = $self->{'table'}->GetColumnIndex($column);
+ return $self->{'values'}->[$column_index];
+ }
+}
+
+
+
+
+sub SetValue ($$$)
+{
+ my ($self, $column, $value) = @_;
+
+ if ($column =~ /^\d+$/)
+ {
+ $self->{'values'}->[$column] = $value;
+ }
+ else
+ {
+ my $column_index = $self->{'table'}->GetColumnIndex($column);
+ $self->{'values'}->[$column_index] = $value;
+ }
+ $self->{'table'}->MarkAsModified();
+}
+
+
+
+
+sub Format ($$)
+{
+ my $self = shift;
+ my $concatenation = shift;
+
+ my $result = "";
+ my $first = 1;
+ my $index = 0;
+ my $column_count = $self->{'table'}->GetColumnCount();
+ foreach my $item (@{$self->{'values'}})
+ {
+ ++$index;
+
+ if ( ! $first)
+ {
+ $result .= $concatenation;
+ }
+ else
+ {
+ $first = 0;
+ }
+ $result .= $item;
+ }
+ return $result;
+}
+
+
+
+
+sub Clone ($$)
+{
+ my ($self, $new_table) = @_;
+
+ my $clone = { %$self };
+ $clone->{'values'} = [ @{$self->{'values'}} ];
+ $clone->{'table'} = $new_table;
+ bless($clone, "MsiRow");
+
+ return $clone;
+}
+
+
+
+
+sub SetTable ($$)
+{
+ my ($self, $new_table) = @_;
+
+ if (defined $self->{'table'} && $self->{'table'} != $new_table)
+ {
+ MsiTools::Die("can not reset table of row");
+ }
+ else
+ {
+ $self->{'table'} = $new_table;
+ }
+}
+
+1;
diff --git a/solenv/bin/modules/installer/patch/MsiTable.pm b/solenv/bin/modules/installer/patch/MsiTable.pm
new file mode 100644
index 0000000..a95b94a
--- /dev/null
+++ b/solenv/bin/modules/installer/patch/MsiTable.pm
@@ -0,0 +1,274 @@
+#**************************************************************
+#
+# 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::MsiTable;
+
+=head1 NAME
+
+ package installer::patch::MsiTable - Class that represents one table of an Msi file.
+
+=cut
+
+use installer::patch::MsiRow;
+
+use strict;
+
+=head new ($class, $filename, $table_name)
+
+ Create a new MsiTable object from the output of a previous
+ msidb.exe run. The table is named $table_name, its data is read
+ from $filename.
+
+=cut
+sub new ($$$)
+{
+ my ($class, $filename, $table_name) = @_;
+
+ my $self = {
+ 'name' => $table_name,
+ 'is_valid' => 1
+ };
+ bless($self, $class);
+
+ if ( -f $filename)
+ {
+ $self->ReadFile($filename);
+ }
+ return $self;
+}
+
+
+
+
+sub IsValid ($)
+{
+ my ($self) = @_;
+ return $self->{'is_valid'};
+}
+
+
+
+
+sub Trim ($)
+{
+ my $line = shift;
+
+ $line =~ s/(^\s+|\s+$)//g;
+
+ return $line;
+}
+
+
+
+=head2 ReadFile($self, $filename)
+
+ Read the content of the table from the specified .idt file.
+ For each row a MsiRow object is appended to $self->{'rows'}.
+
+=cut
+sub ReadFile ($$)
+{
+ my ($self, $filename) = @_;
+
+ if ( ! (-f $filename && -r $filename))
+ {
+ printf STDERR ("can not open idt file %s for reading\n", $filename);
+ $self->{'is_valid'} = 0;
+ return;
+ }
+
+ open my $in, "<", $filename;
+
+ my $columns = Trim(<$in>);
+ $self->{'columns'} = [split(/\t/, $columns)];
+
+ my $column_specs = Trim(<$in>);
+ $self->{'column_specs'} = [split(/\t/, $column_specs)];
+
+ # Table name, index columns.
+ my $line = Trim(<$in>);
+ my @items = split(/\t/, $line);
+ if (scalar @items == 3)
+ {
+ $self->{'codepage'} = shift @items;
+ }
+ my $table_name = shift @items;
+ if ($table_name ne $self->{'name'})
+ {
+ printf STDERR ("reading wrong table data for table '%s' (got %s)\n", $self->{'name'}, $table_name);
+ $self->{'is_valid'} = 0;
+ return;
+ }
+ $self->{'index_columns'} = [@items];
+ $self->{'index_column_index'} = $self->GetColumnIndex($items[0]);
+
+ my $rows = [];
+ while (<$in>)
+ {
+ # Remove all trailing returns and newlines. Keep trailing spaces and tabs.
+ s/[\r\n]+$//g;
+
+ my @items = split(/\t/, $_);
+ push @$rows, new installer::patch::MsiRow($self, @items);
+ }
+ $self->{'rows'} = $rows;
+
+ return $self;
+}
+
+
+
+=head2 GetColumnCount($self)
+
+ Return the number of columns in the table.
+
+=cut
+sub GetColumnCount ($)
+{
+ my ($self) = @_;
+
+ return scalar @{$self->{'columns'}};
+}
+
+
+
+
+=head2 GetRowCount($self)
+
+ Return the number of rows in the table.
+
+=cut
+sub GetRowCount ($)
+{
+ my ($self) = @_;
+
+ return scalar @{$self->{'rows'}};
+}
+
+
+
+
+=head2 GetColumnIndx($self, $column_name)
+
+ Return the 0 based index of the column named $column_name. Use
+ this to speed up (slightly) access to column values when accessing
+ many or all rows of a table.
+
+=cut
+sub GetColumnIndex ($$)
+{
+ my ($self, $column_name) = @_;
+
+ my $index = 0;
+ foreach my $name (@{$self->{'columns'}})
+ {
+ if ($name eq $column_name)
+ {
+ return $index;
+ }
+ ++$index;
+ }
+
+ printf STDERR ("did not find column %s in %s\n", $column_name, join(" and ", @{$self->{'columns'}}));
+ return -1;
+}
+
+
+
+
+=head2 GetValue($self, $selector_column, $selector_column_value, $value_column)
+
+ Find the row in which the $selector_column has value
+ $selector_column_value and return its value in the $value_column.
+
+=cut
+
+sub GetValue ($$$$)
+{
+ my ($self, $selector_column, $selector_column_value, $value_column) = @_;
+
+ my $row = $self->GetRow($selector_column, $selector_column_value);
+ if (defined $row)
+ {
+ return $row->GetValue($value_column);
+ }
+ else
+ {
+ return undef;
+ }
+}
+
+
+
+
+=head2 GetRow($self, $column, $value)
+
+ Return the (first) row which has $value in $column.
+
+=cut
+sub GetRow ($$$)
+{
+ my ($self, $column, $value) = @_;
+
+ my $column_index = $self->GetColumnIndex($column);
+ if ($column_index<0)
+ {
+ printf STDERR "ERROR: unknown column $column in table $self->{'name'}\n";
+ return undef;
+ }
+
+ foreach my $row (@{$self->{'rows'}})
+ {
+ if ($row->GetValue($column_index) eq $value)
+ {
+ return $row;
+ }
+ }
+
+ printf STDERR ("ERROR: did not find row for %s->%s in %s\n",
+ $column,
+ $value,
+ table $self->{'name'});
+
+ return undef;
+}
+
+
+
+
+=head2 GetAllRows ($self)
+
+ Return the reference to an array that contains all rows of the table.
+
+=cut
+
+sub GetAllRows ($)
+{
+ my $self = shift;
+
+ return $self->{'rows'};
+}
+
+
+
+
+
+1;
diff --git a/solenv/bin/modules/installer/patch/ReleasesList.pm b/solenv/bin/modules/installer/patch/ReleasesList.pm
new file mode 100644
index 0000000..320e864
--- /dev/null
+++ b/solenv/bin/modules/installer/patch/ReleasesList.pm
@@ -0,0 +1,210 @@
+#**************************************************************
+#
+# 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::ReleasesList;
+
+use XML::LibXML;
+use File::Spec;
+use strict;
+
+=head1 NAME
+
+ package installer::patch::ReleasesList - Functions for accessing the instsetoo_native/data/releases.xml file
+
+=cut
+
+
+my $Instance = undef;
+
+=head2 Instance()
+
+ Return the singleton instance.
+
+=cut
+sub Instance()
+{
+ if ( ! defined $Instance)
+ {
+ $Instance = new installer::patch::ReleasesList();
+ }
+ return $Instance;
+}
+
+
+
+
+=head2 new($class)
+
+ Internal constructor. Don't call.
+
+=cut
+sub new ($)
+{
+ my ($class) = @_;
+
+ my $self = {};
+ bless($self, $class);
+
+ $self->Read();
+
+ return $self;
+}
+
+
+
+
+=head2 GetFirstChild ($node, $child_name)
+
+ Internal function that returns the first child. Use only when the
+ first child is the (expected) only child in a list.
+
+=cut
+sub GetFirstChild ($$)
+{
+ my ($node, $child_name) = @_;
+
+ if ( ! defined $node)
+ {
+ return undef;
+ }
+ else
+ {
+ my @child_nodes = $node->getElementsByTagName($child_name);
+ if (scalar @child_nodes == 0)
+ {
+ return undef;
+ }
+ else
+ {
+ return $child_nodes[0];
+ }
+ }
+}
+
+
+
+
+=head2 GetText ($node)
+
+ Internal function that returns the trimmed text content of a node.
+
+=cut
+sub GetText ($)
+{
+ my ($node) = @_;
+
+ if ( ! defined $node)
+ {
+ return "";
+ }
+ else
+ {
+ my $text = $node->textContent();
+ $text =~ s/(^\s+|\s+$)//g;
+ return $text;
+ }
+}
+
+
+
+
+=head2 Read($self)
+
+ Read the releases.xml file as doctree and parse its content.
+
+=cut
+sub Read ($)
+{
+ my ($self) = @_;
+
+ my $filename = File::Spec->catfile($ENV{'SRC_ROOT'}, "instsetoo_native", "data", "releases.xml");
+ my $parser = XML::LibXML->new();
+ my $document = $parser->parse_file($filename);
+ foreach my $release_node ($document->getElementsByTagName("release"))
+ {
+ my $version_node = GetFirstChild($release_node, "version");
+ my $version = GetText($version_node);
+ next if $version eq "";
+
+ foreach my $download_node (GetFirstChild($release_node, "download"))
+ {
+ my $package_node = GetFirstChild($download_node, "package-format");
+ my $package_format = GetText($package_node);
+ next if $package_format eq "";
+
+ my $download_data = ParseDownloadData($download_node);
+ if (defined $download_data)
+ {
+ $self->{$version}->{$package_format} = $download_data;
+ }
+ }
+ }
+
+}
+
+
+
+
+=head2 ParseDownloadData ($download_node)
+
+ Parse the data for one set of download data (there is one per release and package format).
+
+=cut
+sub ParseDownloadData ($)
+{
+ my ($download_node) = @_;
+
+ my $url_node = GetFirstChild($download_node, "url-template");
+ my $url_template = GetText($url_node);
+ if ($url_template eq "")
+ {
+ print STDERR "releases data file corrupt (no URL template)\n";
+ return undef;
+ }
+
+ my $download_data = {};
+ foreach my $item_node (@{$download_node->getElementsByTagName("item")})
+ {
+ my $language = GetText(GetFirstChild($item_node, "language"));
+ my $checksum_node = GetFirstChild($item_node, "checksum");
+ if ( ! defined $checksum_node)
+ {
+ print STDERR "releases data file corrupt (item has no 'checksum' node)\n";
+ return undef;
+ }
+ my $checksum_type = $checksum_node->getAttribute("type");
+ my $checksum_value = GetText($checksum_node);
+ my $file_size = GetText(GetFirstChild($item_node, "size"));
+
+ my $url = $url_template;
+ $url =~ s/\%L/$language/g;
+ $download_data->{$language} = {
+ 'URL' => $url,
+ 'checksum-type' => $checksum_type,
+ 'checksum-value' => $checksum_value,
+ 'file-size' => $file_size
+ };
+ }
+
+ return $download_data;
+}
+
+1;
diff --git a/solenv/bin/modules/installer/patch/Tools.pm b/solenv/bin/modules/installer/patch/Tools.pm
new file mode 100644
index 0000000..b29b559
--- /dev/null
+++ b/solenv/bin/modules/installer/patch/Tools.pm
@@ -0,0 +1,47 @@
+#**************************************************************
+#
+# 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::Tools;
+
+=head1 NAME
+
+ package installer::patch::Tools - Collection of functions that don't fit anywhere else
+
+=cut
+
+
+
+
+=head2 CygpathToWindows ($path)
+
+ Convert the given path with the 'cygpath' command into Windows format. Quote backslashes.
+
+=cut
+sub CygpathToWindows($)
+{
+ my ($path) = @_;
+ my $windows_path = qx(cygpath -w "$path");
+ $windows_path =~ s/(^\s+|\s+$)//g;
+ $windows_path =~ s/\\/\\\\/g;
+ return $windows_path;
+}
+
+1;
diff --git a/solenv/bin/modules/installer/patch/Version.pm b/solenv/bin/modules/installer/patch/Version.pm
new file mode 100644
index 0000000..685df6d
--- /dev/null
+++ b/solenv/bin/modules/installer/patch/Version.pm
@@ -0,0 +1,74 @@
+#**************************************************************
+#
+# 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::Version;
+
+
+=head1 NAME
+
+ package installer::patch::Version - Functions for handling version numbers.
+
+=cut
+
+
+
+# We handle version numbers that consist of three parts: major, minor and micro version number.
+my $VersionPartCount = 3;
+
+
+
+=head StringToNumberArray($version_string)
+
+ Convert a version string (where the individual parts are separated by '.') into an array of three numbers.
+ Missing numbers are filled with 0.
+
+ Returns an array with three elements (major, minor, micro).
+=cut
+sub StringToNumberArray ($)
+{
+ my ($version_string) = @_;
+
+ my @version_parts = split(/\./, $version_string);
+ while (scalar @version_parts < $VersionPartCount)
+ {
+ push @version_parts, "0";
+ }
+ return @version_parts;
+}
+
+
+
+
+=head ArrayToDirectoryName (@)
+
+ Return a directory name (without any path) for the given array of version numbers.
+
+=cut
+sub ArrayToDirectoryName (@)
+{
+ return "v-".join("-", @_);
+}
+
+
+
+
+
+1;
diff --git a/solenv/bin/patch_make_releases_xml.pl b/solenv/bin/patch_make_releases_xml.pl
new file mode 100644
index 0000000..b75046b
--- /dev/null
+++ b/solenv/bin/patch_make_releases_xml.pl
@@ -0,0 +1,197 @@
+#!/usr/bin/perl -w
+
+#**************************************************************
+#
+# 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.
+#
+#**************************************************************
+
+use LWP::UserAgent;
+
+use strict;
+
+=head1 NAME
+
+ patch_make_releases_xml.pl - Create a section for the instsetoo_native/data/releases.xml file.
+
+=head1 SYNOPSIS
+
+ patch_make_releases_xml.pl <version-number>
+
+ version-number is the version number (eg 4.0.1) for which to create the releases.xml file.
+
+=head1 DESCRIPTION
+
+ Will contact http://archive.apache.org/dist/openoffice/<version-number>/binaries/ and
+ a) determine the set of languages
+ b) collect sizes and sha256 check sums for all Windows installation sets.
+
+ The result is printed to the console. It has to be added manually to releases.xml.
+
+=cut
+
+
+if (scalar @ARGV != 1)
+{
+ print STDERR "usage: $0 <version-number>\n";
+ die;
+}
+
+my $version = $ARGV[0];
+
+print <<EOT;
+<?xml version='1.0' encoding='UTF-8'?>
+<!--***********************************************************
+ *
+ * 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.
+ *
+ ***********************************************************-->
+EOT
+
+sub DownloadFile ($)
+{
+ my $url = shift;
+
+ my $agent = LWP::UserAgent->new();
+ $agent->timeout(120);
+ $agent->show_progress(0);
+
+ my $file_content = "";
+ 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.
+ $file_content = "";
+ }
+ my($response,$agent,$h,$data)=@_;
+ $file_content .= $data;
+ });
+ $agent->get($url);
+
+ return $file_content;
+}
+
+
+
+
+sub GetResponse ($)
+{
+ my $url = shift;
+
+ my $agent = LWP::UserAgent->new();
+ $agent->timeout(120);
+ $agent->show_progress(0);
+
+ my $file_content = "";
+ 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.
+ $file_content = "";
+ }
+ my($response,$agent,$h,$data)=@_;
+ $file_content .= $data;
+ });
+ return $agent->get($url, 'Range' => "bytes=0-0");
+}
+
+my @languages = ();
+my @lines = split(/\n/, DownloadFile("http://archive.apache.org/dist/openoffice/".$version."/binaries/"));
+foreach my $line (@lines)
+{
+ next unless $line =~ /folder.gif/;
+ if ($line =~ /a href=\"([^\"\/]+)\/\"/)
+ {
+ my $language = $1;
+ next if $language eq "SDK";
+ next if $language =~ /^[A-Z]/;
+ push @languages, $language;
+ }
+}
+
+print "<releases>\n";
+print " <release>\n";
+printf " <version>%s</version>\n", $version;
+print " <download>\n";
+print " <package-format>msi</package-format>\n";
+print " <url-template>\n";
+printf " http://archive.apache.org/dist/openoffice/%s/binaries/%%L/Apache_OpenOffice_%s_Win_x86_install_%%L.exe\n",$version, $version;
+print " </url-template>\n";
+foreach my $language (sort @languages)
+{
+ print " <item>\n";
+ printf " <language>%s</language>\n", $language;
+ my $name = sprintf(
+ "Apache_OpenOffice_%s_Win_x86_install_%s.exe",
+ $version,
+ $language,
+ $version,
+ $language);
+
+ my $content = DownloadFile(
+ sprintf("http://archive.apache.org/dist/openoffice/%s/binaries/%s/%s.sha256", $version, $language, $name));
+ if ($content =~ /^([a-f0-9]+)/)
+ {
+ printf(" <checksum type=\"sha256\">%s</checksum>\n", $1);
+ }
+ my $response = GetResponse(
+ sprintf("http://archive.apache.org/dist/openoffice/%s/binaries/%s/%s", $version, $language, $name));
+ my $content_range = $response->{'_headers'}->{'content-range'};
+ if ($content_range =~ /bytes 0-0\/(\d+)/)
+ {
+ printf(" <size>%s</size>\n", $1);
+ }
+ print " </item>\n";
+}
+
+print " </download>\n";
+print " </release>\n";
+print "</releases>\n";
diff --git a/solenv/bin/release_prepare.pl b/solenv/bin/release_prepare.pl
new file mode 100644
index 0000000..129358a
--- /dev/null
+++ b/solenv/bin/release_prepare.pl
@@ -0,0 +1,226 @@
+#!/usr/bin/perl -w
+
+#**************************************************************
+#
+# 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.
+#
+#**************************************************************
+
+use lib ("$ENV{SOLARENV}/bin/modules");
+use installer::patch::InstallationSet;
+use installer::patch::Msi;
+use installer::patch::ReleasesList;
+use installer::ziplist;
+use installer::logger;
+
+use Getopt::Long;
+use Pod::Usage;
+use Digest;
+
+use strict;
+
+=head1 NAME
+
+ release_prepare.pl - Several functions to prepare release builds
+
+=head1 SYNOPSIS
+
+ release_prepare.pl [options] <language1> <language2> ...
+
+ Options:
+ --lst-file <filename>
+ Path to the .lst file, eg ../util/openoffice.lst
+ --product-name <product-name>
+ The product name, eg Apache_OpenOffice
+ --output-path <path>
+ Path to the instsetoo_native platform output tree
+ --source-version <major>.<minor>.<micro>
+ Override version number of the source. If not given it is computed from the target version.
+
+=head1 DESCRIPTION
+
+ Prepare a release build:
+
+ - Provide installation sets of the previous version.
+ If they are not in ext_sources/ then they are downloaded.
+
+ - Unpack the installation sets.
+
+=cut
+
+
+sub ProcessCommandline ()
+{
+ my $arguments = {
+ 'lst-file' => undef,
+ 'product-name' => undef,
+ 'output-path' => undef,
+ 'source-version' => undef};
+
+ if ( ! GetOptions(
+ "lst-file=s", \$arguments->{'lst-file'},
+ "product-name=s", \$arguments->{'product-name'},
+ "output-path=s", \$arguments->{'output-path'},
+ "source-version:s" => \$arguments->{'source-version'}
+ ))
+ {
+ pod2usage(1);
+ }
+
+ if ( ! defined $arguments->{'lst-file'})
+ {
+ print STDERR "lst-file missing, please provide --lst-file\n";
+ pod2usage(2);
+ }
+ if ( ! defined $arguments->{'product-name'})
+ {
+ print STDERR "product name missing, please provide --product-name\n";
+ pod2usage(2);
+ }
+ if ( ! defined $arguments->{'output-path'})
+ {
+ print STDERR "output path missing, please provide --output-path\n";
+ pod2usage(2);
+ }
+
+ $arguments->{'languages'} = \@ARGV;
+
+ return $arguments;
+}
+
+
+
+
+sub ProcessLanguage ($$$$)
+{
+ my ($source_version, $language, $package_format, $product_name) = @_;
+
+ $installer::logger::Info->printf("%s\n", $language);
+ $installer::logger::Info->increase_indentation();
+
+ # For every language we need
+ # 1. have downloadable installation set available (download if missing)
+ # 2. unpack it to get access to .cab and .msi
+ # 3. unpack .cab so that msimsp.exe can be run
+
+ # Create paths to unpacked contents of .exe and .cab and determine if they exist.
+ # The existence of these paths is taken as flag whether the unpacking has already taken place.
+ my $unpacked_exe_path = installer::patch::InstallationSet::GetUnpackedMsiPath(
+ $source_version,
+ $language,
+ $package_format,
+ $product_name);
+ my $unpacked_cab_path = installer::patch::InstallationSet::GetUnpackedCabPath(
+ $source_version,
+ $language,
+ $package_format,
+ $product_name);
+ my $exe_is_unpacked = -d $unpacked_exe_path;
+ my $cab_is_unpacked = -d $unpacked_cab_path;
+
+ if ( ! $exe_is_unpacked)
+ {
+ # Interpret existence of path as proof that the installation
+ # set and the cab file have been successfully unpacked.
+ # Nothing to do.
+ my $filename = installer::patch::InstallationSet::ProvideDownloadSet(
+ $source_version,
+ $language,
+ $package_format);
+ if (defined $filename)
+ {
+ if ( ! -d $unpacked_exe_path)
+ {
+ installer::patch::InstallationSet::UnpackExe($filename, $unpacked_exe_path);
+ }
+ }
+ else
+ {
+ installer::logger::PrintError("could not provide .exe installation set at '%s'\n", $filename);
+ }
+ }
+ else
+ {
+ $installer::logger::Info->printf("downloadable installation set has already been unpacked to '%s'\n",
+ $unpacked_exe_path);
+ }
+
+ if ( ! $cab_is_unpacked)
+ {
+ my $cab_filename = File::Spec->catfile($unpacked_exe_path, "openoffice1.cab");
+ 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);
+ }
+
+ # Unpack the cab file.
+ my $msi = new installer::patch::Msi(
+ $source_version,
+ $language,
+ $product_name);
+
+ $installer::logger::Info->printf("unpacking cab file '%s' to '%s'\n",
+ $cab_filename, $unpacked_cab_path);
+ installer::patch::InstallationSet::UnpackCab(
+ $cab_filename,
+ $msi,
+ $unpacked_cab_path);
+ }
+ else
+ {
+ $installer::logger::Info->printf("cab has already been unpacked to\n");
+ $installer::logger::Info->printf(" %s\n", $unpacked_cab_path);
+ }
+
+ $installer::logger::Info->decrease_indentation();
+}
+
+
+
+
+installer::logger::SetupSimpleLogging("c:/tmp/log");
+
+my $arguments = ProcessCommandline();
+$arguments->{'package-format'} = 'msi';
+
+print "preparing release build\n";
+my ($variables, undef, undef)
+ = installer::ziplist::read_openoffice_lst_file(
+ $arguments->{'lst-file'},
+ $arguments->{'product-name'},
+ undef);
+if ( ! defined $arguments->{'source-version'})
+{
+ $arguments->{'source-version'} = $variables->{'PREVIOUS_VERSION'};
+}
+$installer::logger::Info->printf(" reading data from '%s'\n", $arguments->{'lst-file'});
+$installer::logger::Info->printf(" product name is '%s'\n", $arguments->{'product-name'});
+$installer::logger::Info->printf(" output path is '%s'\n", $arguments->{'output-path'});
+$installer::logger::Info->printf(" source version is '%s'\n", $arguments->{'source-version'});
+
+foreach my $language (@{$arguments->{'languages'}})
+{
+ ProcessLanguage(
+ $arguments->{'source-version'},
+ $language,
+ $arguments->{'package-format'},
+ $arguments->{'product-name'});
+}
commit a0e2aa57219a86c722bca890de349897cc479725
Author: Andre Fischer <af at apache.org>
Date: Tue Nov 12 13:37:30 2013 +0000
123531: Removed the old and incomplete support for updates (patches).
diff --git a/instsetoo_native/util/openoffice.lst b/instsetoo_native/util/openoffice.lst
index 82ac49b..3b0bb5d 100644
--- a/instsetoo_native/util/openoffice.lst
+++ b/instsetoo_native/util/openoffice.lst
@@ -27,9 +27,7 @@ Globals
NATIVEPROGRESS false
REGISTRYLAYERNAME Layers
SERVICEPACK 1
- UPDATE_DATABASE 1
CREATE_MSP_INSTALLSET 0
- UPDATE_DATABASE_LISTNAME finals_instsetoo.txt
PACKAGEMAP package_names.txt,package_names_ext.txt
WINDOWSPATCHLEVEL 8
OOOVENDOR Apache Software Foundation
diff --git a/setup_native/source/packinfo/finals_instsetoo.txt b/setup_native/source/packinfo/finals_instsetoo.txt
deleted file mode 100644
index d37a921..0000000
--- a/setup_native/source/packinfo/finals_instsetoo.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-# *************************************************************
-#
-# 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.
-#
-# *************************************************************
-
-# Comment line
-# Syntax:
-# Column 1: Product
-# Column 2: pro or nonpro
-# Column 3: languages, comma separated list
-# Column 4: path to msi database in installation set
-# Separator between columns is one or more than one tabulator
-
-# Examples:
-# OpenOffice pro en-US \\<server>\<path>\msi\OOO300_m6_native_packed-1_en-US.9352\openofficeorg30.msi
-# OpenOffice pro en-US,de,es \\<server>\<path>\msi\OOO300_m6_native_packed-1_en-US_de_es.9352\openofficeorg30.msi
-# OpenOffice pro de \\<server>\<path>\msi\OOO300_m6_native_packed-1_de.9352\openofficeorg30.msi
-# OpenOfficeLanguagePack pro es \\<server>\<path>\msi\OOO300_m6_native_packed-1_es.9352\openofficeorg30.msi
-# URE pro en-US \\<server>\<path>\msi\OOO300_m6_native_packed-1_en-US.9352\ure14.msi
diff --git a/solenv/bin/make_installer.pl b/solenv/bin/make_installer.pl
index 4b56528..0837e56 100644
--- a/solenv/bin/make_installer.pl
+++ b/solenv/bin/make_installer.pl
@@ -75,7 +75,6 @@ use installer::windows::inifile;
use installer::windows::java;
use installer::windows::media;
use installer::windows::msiglobal;
-use installer::windows::msp;
use installer::windows::patch;
use installer::windows::property;
use installer::windows::removefile;
@@ -83,7 +82,6 @@ use installer::windows::registry;
use installer::windows::selfreg;
use installer::windows::shortcut;
use installer::windows::strip;
-use installer::windows::update;
use installer::windows::upgrade;
use installer::worker;
use installer::xpdinstaller;
@@ -709,30 +707,11 @@ for ( my $n = 0; $n <= $#installer::globals::languageproducts; $n++ )
my $uniquefilename = "";
my $revuniquefilename = "";
my $revshortfilename = "";
- my $allupdatesequences = "";
- my $allupdatecomponents = "";
- my $allupdatefileorder = "";
my $allupdatecomponentorder = "";
my $shortdirname = "";
my $componentid = "";
my $componentidkeypath = "";
my $alloldproperties = "";
- my $allupdatelastsequences = "";
- my $allupdatediskids = "";
-
- if ( $installer::globals::iswindowsbuild )
- {
- if ( $allvariableshashref->{'UPDATE_DATABASE'} )
- {
- $installer::logger::Info->print( "... analyzing update database ...\n" );
- $refdatabase = installer::windows::update::readdatabase($allvariableshashref, $languagestringref, $includepatharrayref);
-
- if ( $installer::globals::updatedatabase )
- {
- ($uniquefilename, $revuniquefilename, $revshortfilename, $allupdatesequences, $allupdatecomponents, $allupdatefileorder, $allupdatecomponentorder, $shortdirname, $componentid, $componentidkeypath, $alloldproperties, $allupdatelastsequences, $allupdatediskids) = installer::windows::update::create_database_hashes($refdatabase);
- }
- }
- }
##############################################
# Setting global code variables for Windows
@@ -1940,9 +1919,8 @@ for ( my $n = 0; $n <= $#installer::globals::languageproducts; $n++ )
# Collection all available directory trees
installer::windows::directory::collectdirectorytrees($directoriesforepmarrayref);
- $filesinproductlanguageresolvedarrayref = installer::windows::file::create_files_table($filesinproductlanguageresolvedarrayref, \@allfilecomponents, $newidtdir, $allvariableshashref, $uniquefilename, $allupdatesequences, $allupdatecomponents, $allupdatefileorder);
+ $filesinproductlanguageresolvedarrayref = installer::windows::file::create_files_table($filesinproductlanguageresolvedarrayref, \@allfilecomponents, $newidtdir, $allvariableshashref, $uniquefilename);
if ( $installer::globals::globallogging ) { installer::files::save_array_of_hashes($loggingdir . "productfiles17c.log", $filesinproductlanguageresolvedarrayref); }
- if ( $installer::globals::updatedatabase ) { installer::windows::file::check_file_sequences($allupdatefileorder, $allupdatecomponentorder); }
installer::windows::directory::create_directory_table($directoriesforepmarrayref, $newidtdir, $allvariableshashref, $shortdirname, $loggingdir);
if ( $installer::globals::globallogging ) { installer::files::save_array_of_hashes($loggingdir . "productfiles18.log", $filesinproductlanguageresolvedarrayref); }
@@ -1966,7 +1944,7 @@ for ( my $n = 0; $n <= $#installer::globals::languageproducts; $n++ )
installer::windows::featurecomponent::create_featurecomponent_table($filesinproductlanguageresolvedarrayref, $registryitemsinproductlanguageresolvedarrayref, $newidtdir);
- installer::windows::media::create_media_table($filesinproductlanguageresolvedarrayref, $newidtdir, $allvariableshashref, $allupdatelastsequences, $allupdatediskids);
+ installer::windows::media::create_media_table($filesinproductlanguageresolvedarrayref, $newidtdir, $allvariableshashref);
if ( $installer::globals::globallogging ) { installer::files::save_array_of_hashes($loggingdir . "productfiles20.log", $filesinproductlanguageresolvedarrayref); }
installer::windows::font::create_font_table($filesinproductlanguageresolvedarrayref, $newidtdir);
@@ -2255,20 +2233,6 @@ for ( my $n = 0; $n <= $#installer::globals::languageproducts; $n++ )
installer::worker::clean_output_tree(); # removing directories created in the output tree
($is_success, $finalinstalldir) = installer::worker::analyze_and_save_logfile($loggingdir, $installdir, $installlogdir, $allsettingsarrayref, $languagestringref, $current_install_number);
- #######################################################
- # Creating Windows msp patches
- #######################################################
-
- if (( $is_success ) && ( $installer::globals::updatedatabase ) && ( $allvariableshashref->{'CREATE_MSP_INSTALLSET'} ))
- {
- # Required:
- # Temp path for administrative installations: $installer::globals::temppath
- # Path of new installation set: $finalinstalldir
- # Path of old installation set: $installer::globals::updatedatabasepath
- my $mspdir = installer::windows::msp::create_msp_patch($finalinstalldir, $includepatharrayref, $allvariableshashref, $languagestringref, $languagesarrayref, $filesinproductlanguageresolvedarrayref);
- ($is_success, $finalinstalldir) = installer::worker::analyze_and_save_logfile($loggingdir, $mspdir, $installlogdir, $allsettingsarrayref, $languagestringref, $current_install_number);
- installer::worker::clean_output_tree(); # removing directories created in the output tree
- }
#######################################################
# Creating download installation set
diff --git a/solenv/bin/modules/installer/globals.pm b/solenv/bin/modules/installer/globals.pm
index d388b5f..e545da8 100644
--- a/solenv/bin/modules/installer/globals.pm
+++ b/solenv/bin/modules/installer/globals.pm
@@ -226,14 +226,8 @@ BEGIN
@linkrpms = ();
$archiveformat = "";
$minorupgradekey = "";
- $updatelastsequence = 0;
- $updatesequencecounter = 0;
- $updatedatabase = 0;
- $updatedatabasepath = "";
$pfffileexists = 0;
$pffcabfilename = "ooobasis3.0_pff.cab";
- %newupdatefiles = ();
- %allusedupdatesequences = ();
$mergefiles_added_into_collector = 0;
$creating_windows_installer_patch = 0;
diff --git a/solenv/bin/modules/installer/windows/component.pm b/solenv/bin/modules/installer/windows/component.pm
index 2804cb5..f285197 100644
--- a/solenv/bin/modules/installer/windows/component.pm
+++ b/solenv/bin/modules/installer/windows/component.pm
@@ -46,11 +46,6 @@ sub get_component_guid
# At this time only a template
my $returnvalue = "\{COMPONENTGUID\}";
- if (( $installer::globals::updatedatabase ) && ( exists($componentidhashref->{$componentname}) ))
- {
- $returnvalue = $componentidhashref->{$componentname};
- }
-
# Returning a ComponentID, that is assigned in scp project
if ( exists($installer::globals::componentid{$componentname}) )
{
diff --git a/solenv/bin/modules/installer/windows/directory.pm b/solenv/bin/modules/installer/windows/directory.pm
index 86be8a2..5c9e5c7 100644
--- a/solenv/bin/modules/installer/windows/directory.pm
+++ b/solenv/bin/modules/installer/windows/directory.pm
@@ -358,8 +358,7 @@ sub create_defaultdir_directorynames
my ($directoryref, $shortdirnamehashref) = @_;
my @shortnames = ();
- if ( $installer::globals::updatedatabase ) { @shortnames = values(%{$shortdirnamehashref}); }
- elsif ( $installer::globals::prepare_winpatch ) { @shortnames = values(%installer::globals::saved83dirmapping); }
+ if ( $installer::globals::prepare_winpatch ) { @shortnames = values(%installer::globals::saved83dirmapping); }
for ( my $i = 0; $i <= $#{$directoryref}; $i++ )
{
@@ -371,11 +370,7 @@ sub create_defaultdir_directorynames
# installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$hostname); # making program/classes to classes
my $uniquename = $onedir->{'uniquename'};
my $shortstring;
- if (( $installer::globals::updatedatabase ) && ( exists($shortdirnamehashref->{$uniquename}) ))
- {
- $shortstring = $shortdirnamehashref->{$uniquename};
- }
- elsif (( $installer::globals::prepare_winpatch ) && ( exists($installer::globals::saved83dirmapping{$uniquename}) ))
+ if (( $installer::globals::prepare_winpatch ) && ( exists($installer::globals::saved83dirmapping{$uniquename}) ))
{
$shortstring = $installer::globals::saved83dirmapping{$uniquename};
}
diff --git a/solenv/bin/modules/installer/windows/file.pm b/solenv/bin/modules/installer/windows/file.pm
index b11f348..9e0169d 100644
--- a/solenv/bin/modules/installer/windows/file.pm
+++ b/solenv/bin/modules/installer/windows/file.pm
@@ -377,16 +377,7 @@ sub generate_unique_filename_for_filetable
installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$uniquefilename); # making /registry/schema/org/openoffice/VCL.xcs to VCL.xcs
# Reading unique filename with help of "Component_" in File table from old database
- if (( $installer::globals::updatedatabase ) && ( exists($uniquefilenamehashref->{"$component/$uniquefilename"}) ))
- {
- $uniquefilename = $uniquefilenamehashref->{"$component/$uniquefilename"}; # syntax of $value: ($uniquename;$shortname)
- if ( $uniquefilename =~ /^\s*(.*?)\;\s*(.*?)\s*$/ ) { $uniquefilename = $1; }
- $lcuniquefilename = lc($uniquefilename);
- $installer::globals::alluniquefilenames{$uniquefilename} = 1;
- $installer::globals::alllcuniquefilenames{$lcuniquefilename} = 1;
- return $uniquefilename;
- }
- elsif (( $installer::globals::prepare_winpatch ) && ( exists($installer::globals::savedmapping{"$component/$uniquefilename"}) ))
+ if (( $installer::globals::prepare_winpatch ) && ( exists($installer::globals::savedmapping{"$component/$uniquefilename"}) ))
{
# If we have a FTK mapping for this component/file, use it.
$installer::globals::savedmapping{"$component/$uniquefilename"} =~ m/^(.*);/;
@@ -473,13 +464,7 @@ sub generate_filename_for_filetable
my $shortstring;
# Reading short string with help of "FileName" in File table from old database
- if (( $installer::globals::updatedatabase ) && ( exists($uniquefilenamehashref->{"$fileref->{'componentname'}/$filename"}) ))
- {
- my $value = $uniquefilenamehashref->{"$fileref->{'componentname'}/$filename"}; # syntax of $value: ($uniquename;$shortname)
- if ( $value =~ /^\s*(.*?)\;\s*(.*?)\s*$/ ) { $shortstring = $2; } # already collected in function "collect_shortnames_from_old_database"
- else { $shortstring = $filename; }
- }
- elsif (( $installer::globals::prepare_winpatch ) && ( exists($installer::globals::savedmapping{"$fileref->{'componentname'}/$filename"}) ))
+ if (( $installer::globals::prepare_winpatch ) && ( exists($installer::globals::savedmapping{"$fileref->{'componentname'}/$filename"}) ))
{
$installer::globals::savedmapping{"$fileref->{'componentname'}/$filename"} =~ m/.*;(.*)/;
if ($1 ne '')
@@ -567,85 +552,6 @@ sub get_fileversion
}
#############################################
-# Returning the sequence for a file
-#############################################
-
-sub get_sequence_for_file
-{
- my ($number, $onefile, $fileentry, $allupdatesequenceshashref, $allupdatecomponentshashref, $allupdatefileorderhashref, $allfilecomponents) = @_;
-
- my $sequence = "";
- my $infoline = "";
- my $pffcomponentname = $onefile->{'componentname'} . "_pff";
-
- if ( $installer::globals::updatedatabase )
- {
- if (( exists($allupdatesequenceshashref->{$onefile->{'uniquename'}}) ) &&
- (( $onefile->{'componentname'} eq $allupdatecomponentshashref->{$onefile->{'uniquename'}} ) ||
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list