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::FileOperations; 23c9b362f6SAndre Fischer 24c9b362f6SAndre Fischeruse File::Basename; 25c9b362f6SAndre Fischeruse File::Copy; 26c9b362f6SAndre Fischeruse IO::Compress::Bzip2; 27c9b362f6SAndre Fischeruse IO::Uncompress::Bunzip2; 28c9b362f6SAndre Fischer 29c9b362f6SAndre Fischermy $CompressionMethod = "bzip2"; 30c9b362f6SAndre Fischer 31c9b362f6SAndre Fischer 32c9b362f6SAndre Fischer=head1 NAME 33c9b362f6SAndre Fischer 34c9b362f6SAndre Fischer package installer::patch::FileOperations - Class for collecting, checking and executing file operations. 35c9b362f6SAndre Fischer 36c9b362f6SAndre Fischer=cut 37c9b362f6SAndre Fischer 38c9b362f6SAndre Fischer 39c9b362f6SAndre Fischersub new ($) 40c9b362f6SAndre Fischer{ 41c9b362f6SAndre Fischer my ($class) = (@_); 42c9b362f6SAndre Fischer 43c9b362f6SAndre Fischer my $self = { 44c9b362f6SAndre Fischer 'operations' => [] 45c9b362f6SAndre Fischer }; 46c9b362f6SAndre Fischer bless($self, $class); 47c9b362f6SAndre Fischer 48c9b362f6SAndre Fischer return $self; 49c9b362f6SAndre Fischer} 50c9b362f6SAndre Fischer 51c9b362f6SAndre Fischer 52c9b362f6SAndre Fischer 53c9b362f6SAndre Fischer 54c9b362f6SAndre Fischersub AddCopyOperation ($$$) 55c9b362f6SAndre Fischer{ 56c9b362f6SAndre Fischer my ($self, $source_name, $target_name) = @_; 57c9b362f6SAndre Fischer 58c9b362f6SAndre Fischer push 59c9b362f6SAndre Fischer @{$self->{'operations'}}, 60c9b362f6SAndre Fischer [ 61c9b362f6SAndre Fischer 'copy', 62c9b362f6SAndre Fischer $source_name, 63c9b362f6SAndre Fischer $target_name 64c9b362f6SAndre Fischer ]; 65c9b362f6SAndre Fischer} 66c9b362f6SAndre Fischer 67c9b362f6SAndre Fischer 68c9b362f6SAndre Fischer 69c9b362f6SAndre Fischer 70c9b362f6SAndre Fischersub AddMakeDirectoryOperation ($$) 71c9b362f6SAndre Fischer{ 72c9b362f6SAndre Fischer my ($self, $path) = @_; 73c9b362f6SAndre Fischer 74c9b362f6SAndre Fischer push 75c9b362f6SAndre Fischer @{$self->{'operations'}}, 76c9b362f6SAndre Fischer [ 77c9b362f6SAndre Fischer 'mkdir', 78c9b362f6SAndre Fischer $path 79c9b362f6SAndre Fischer ]; 80c9b362f6SAndre Fischer} 81c9b362f6SAndre Fischer 82c9b362f6SAndre Fischer 83c9b362f6SAndre Fischer 84c9b362f6SAndre Fischer 85c9b362f6SAndre Fischersub AddCompressOperation ($$) 86c9b362f6SAndre Fischer{ 87c9b362f6SAndre Fischer my ($self, $filename) = @_; 88c9b362f6SAndre Fischer 89c9b362f6SAndre Fischer push 90c9b362f6SAndre Fischer @{$self->{'operations'}}, 91c9b362f6SAndre Fischer [ 92c9b362f6SAndre Fischer 'compress', 93c9b362f6SAndre Fischer $filename 94c9b362f6SAndre Fischer ]; 95c9b362f6SAndre Fischer} 96c9b362f6SAndre Fischer 97c9b362f6SAndre Fischer 98c9b362f6SAndre Fischer 99c9b362f6SAndre Fischer 100c9b362f6SAndre Fischersub AddUncompressOperation ($$$) 101c9b362f6SAndre Fischer{ 102c9b362f6SAndre Fischer my ($self, $source_name, $target_name) = @_; 103c9b362f6SAndre Fischer 104c9b362f6SAndre Fischer push 105c9b362f6SAndre Fischer @{$self->{'operations'}}, 106c9b362f6SAndre Fischer [ 107c9b362f6SAndre Fischer 'uncompress', 108c9b362f6SAndre Fischer $source_name, 109c9b362f6SAndre Fischer $target_name 110c9b362f6SAndre Fischer ]; 111c9b362f6SAndre Fischer} 112c9b362f6SAndre Fischer 113c9b362f6SAndre Fischer 114c9b362f6SAndre Fischer 115c9b362f6SAndre Fischer 116c9b362f6SAndre Fischersub Check ($) 117c9b362f6SAndre Fischer{ 118c9b362f6SAndre Fischer my ($self) = @_; 119c9b362f6SAndre Fischer 120c9b362f6SAndre Fischer # Keep track of which directories or files would be created to check if 121c9b362f6SAndre Fischer # operations that depend on these files will succeed. 122c9b362f6SAndre Fischer my %files = (); 123c9b362f6SAndre Fischer my %directories = (); 124c9b362f6SAndre Fischer 125c9b362f6SAndre Fischer my @error_messages = (); 126c9b362f6SAndre Fischer foreach my $operation (@{$self->{'operations'}}) 127c9b362f6SAndre Fischer { 128c9b362f6SAndre Fischer my $command = $operation->[0]; 129c9b362f6SAndre Fischer 130c9b362f6SAndre Fischer if ($command eq "copy") 131c9b362f6SAndre Fischer { 132c9b362f6SAndre Fischer my ($source_name, $destination_name) = ($operation->[1], $operation->[2]); 133c9b362f6SAndre Fischer if ( ! -f $source_name) 134c9b362f6SAndre Fischer { 135c9b362f6SAndre Fischer push @error_messages, sprintf("%s is not a regular file and can not be copied", $source_name); 136c9b362f6SAndre Fischer } 137c9b362f6SAndre Fischer my $destination_path = dirname($destination_name); 138c9b362f6SAndre Fischer if ( ! -d $destination_path && ! defined $directories{$destination_path}) 139c9b362f6SAndre Fischer { 140c9b362f6SAndre Fischer push @error_messages, sprintf("destination path %s does not exist", $destination_path); 141c9b362f6SAndre Fischer } 142c9b362f6SAndre Fischer if ( -f $destination_name) 143c9b362f6SAndre Fischer { 144c9b362f6SAndre Fischer # The destination file already exists. We have to overwrite it. 145c9b362f6SAndre Fischer if ( ! -w $destination_name) 146c9b362f6SAndre Fischer { 147c9b362f6SAndre Fischer push @error_messges, sprintf("destination file %s exists but can not be overwritten", $destination_name); 148c9b362f6SAndre Fischer } 149c9b362f6SAndre Fischer } 150c9b362f6SAndre Fischer $files{$destination_name} = 1; 151c9b362f6SAndre Fischer } 152c9b362f6SAndre Fischer elsif ($command eq "mkdir") 153c9b362f6SAndre Fischer { 154c9b362f6SAndre Fischer my $path = $operation->[1]; 155c9b362f6SAndre Fischer if ( -d $path) 156c9b362f6SAndre Fischer { 157c9b362f6SAndre Fischer # Directory already exists. That is OK, the mkdir command will be silently ignored. 158c9b362f6SAndre Fischer } 159c9b362f6SAndre Fischer else 160c9b362f6SAndre Fischer { 161c9b362f6SAndre Fischer $directories{$path} = 1; 162c9b362f6SAndre Fischer } 163c9b362f6SAndre Fischer } 164c9b362f6SAndre Fischer elsif ($command eq "compress") 165c9b362f6SAndre Fischer { 166c9b362f6SAndre Fischer my $filename = $operation->[1]; 167c9b362f6SAndre Fischer if ( ! -f $filename && ! defined $files{$filename}) 168c9b362f6SAndre Fischer { 169c9b362f6SAndre Fischer # File does not exist and will not be created by an earlier operation. 170c9b362f6SAndre Fischer push @error_messages, sprintf("file %s does not exist and can not be compressed", $filename); 171c9b362f6SAndre Fischer } 172c9b362f6SAndre Fischer } 173c9b362f6SAndre Fischer elsif ($command eq "uncompress") 174c9b362f6SAndre Fischer { 175c9b362f6SAndre Fischer my ($source_filename, $destination_filename) = ($operation->[1], $operation->[2]); 176c9b362f6SAndre Fischer if ($CompressionMethod eq "bzip2") 177c9b362f6SAndre Fischer { 178c9b362f6SAndre Fischer $source_filename .= ".bz2"; 179c9b362f6SAndre Fischer } 180c9b362f6SAndre Fischer if ( ! -f $source_filename && ! defined $files{$source_filename}) 181c9b362f6SAndre Fischer { 182c9b362f6SAndre Fischer # File does not exist and will not be created by an earlier operation. 183c9b362f6SAndre Fischer push @error_messages, sprintf("file %s does not exist and can not be decompressed", $source_filename); 184c9b362f6SAndre Fischer } 185c9b362f6SAndre Fischer if ( -f $destination_filename && ! -w $destination_filename) 186c9b362f6SAndre Fischer { 187*30acf5e8Spfg # Destination file already exists but can not be replaced. 188c9b362f6SAndre Fischer push @error_messages, sprintf("compress destination file %s exists but can not be replaced", $destination_filename); 189c9b362f6SAndre Fischer } 190c9b362f6SAndre Fischer } 191c9b362f6SAndre Fischer else 192c9b362f6SAndre Fischer { 193c9b362f6SAndre Fischer push @error_messages, sprintf("unknown operation %s", $command); 194c9b362f6SAndre Fischer } 195c9b362f6SAndre Fischer } 196c9b362f6SAndre Fischer 197c9b362f6SAndre Fischer return @error_messages; 198c9b362f6SAndre Fischer} 199c9b362f6SAndre Fischer 200c9b362f6SAndre Fischer 201c9b362f6SAndre Fischer 202c9b362f6SAndre Fischer 203c9b362f6SAndre Fischersub CheckAndExecute ($) 204c9b362f6SAndre Fischer{ 205c9b362f6SAndre Fischer my ($self) = @_; 206c9b362f6SAndre Fischer 207c9b362f6SAndre Fischer my @error_messages = $self->Check(); 208c9b362f6SAndre Fischer if (scalar @error_messages > 0) 209c9b362f6SAndre Fischer { 210c9b362f6SAndre Fischer $installer::logger::Lang->printf("can not execute all operations:\n"); 211c9b362f6SAndre Fischer for my $message (@error_messages) 212c9b362f6SAndre Fischer { 213c9b362f6SAndre Fischer $installer::logger::Lang->printf("ERROR: %s\n", $message); 214c9b362f6SAndre Fischer } 215c9b362f6SAndre Fischer return 0; 216c9b362f6SAndre Fischer } 217c9b362f6SAndre Fischer else 218c9b362f6SAndre Fischer { 219c9b362f6SAndre Fischer return $self->Execute(); 220c9b362f6SAndre Fischer } 221c9b362f6SAndre Fischer} 222c9b362f6SAndre Fischer 223c9b362f6SAndre Fischer 224c9b362f6SAndre Fischer 225c9b362f6SAndre Fischer 226c9b362f6SAndre Fischersub Execute ($) 227c9b362f6SAndre Fischer{ 228c9b362f6SAndre Fischer my ($self) = @_; 229c9b362f6SAndre Fischer 230c9b362f6SAndre Fischer foreach my $operation (@{$self->{'operations'}}) 231c9b362f6SAndre Fischer { 232c9b362f6SAndre Fischer my $command = $operation->[0]; 233c9b362f6SAndre Fischer 234c9b362f6SAndre Fischer if ($command eq "copy") 235c9b362f6SAndre Fischer { 236c9b362f6SAndre Fischer my ($source_name, $destination_name) = ($operation->[1], $operation->[2]); 237c9b362f6SAndre Fischer $installer::logger::Lang->printf("copy from %s\n to %s\n", $source_name, $destination_name); 238c9b362f6SAndre Fischer if ( ! $DryRun) 239c9b362f6SAndre Fischer { 240c9b362f6SAndre Fischer my $result = copy($source_name, $destination_name); 241c9b362f6SAndre Fischer if ( ! $result) 242c9b362f6SAndre Fischer { 243c9b362f6SAndre Fischer $installer::logger::Lang->printf("ERROR: copying from %s to %s failed", 244c9b362f6SAndre Fischer $source_name, $destination_name); 245c9b362f6SAndre Fischer } 246c9b362f6SAndre Fischer } 247c9b362f6SAndre Fischer } 248c9b362f6SAndre Fischer elsif ($command eq "mkdir") 249c9b362f6SAndre Fischer { 250c9b362f6SAndre Fischer my $path = $operation->[1]; 251c9b362f6SAndre Fischer if ( -d $path) 252c9b362f6SAndre Fischer { 253c9b362f6SAndre Fischer # Path exists already. Do nothing. 254c9b362f6SAndre Fischer } 255c9b362f6SAndre Fischer else 256c9b362f6SAndre Fischer { 257c9b362f6SAndre Fischer $installer::logger::Lang->printf("creating directory %s\n", $path); 258c9b362f6SAndre Fischer if ( ! $DryRun) 259c9b362f6SAndre Fischer { 260c9b362f6SAndre Fischer if (File::Path::make_path($path, {'mode' => 0775}) == 0) 261c9b362f6SAndre Fischer { 262c9b362f6SAndre Fischer $installer::logger::Lang->printf("could not create directory %s\n", $path); 263c9b362f6SAndre Fischer } 264c9b362f6SAndre Fischer } 265c9b362f6SAndre Fischer } 266c9b362f6SAndre Fischer } 267c9b362f6SAndre Fischer elsif ($command eq "compress") 268c9b362f6SAndre Fischer { 269c9b362f6SAndre Fischer my $filename = $operation->[1]; 270c9b362f6SAndre Fischer $installer::logger::Lang->printf("compressing %s\n", $filename); 271c9b362f6SAndre Fischer if ( ! $DryRun) 272c9b362f6SAndre Fischer { 273c9b362f6SAndre Fischer my $result = 0; 274c9b362f6SAndre Fischer if ($CompressionMethod eq "bzip2") 275c9b362f6SAndre Fischer { 276c9b362f6SAndre Fischer $result = IO::Compress::Bzip2::bzip2($filename => $filename.".bz2"); 277c9b362f6SAndre Fischer } 278c9b362f6SAndre Fischer if ($result == 0) 279c9b362f6SAndre Fischer { 280c9b362f6SAndre Fischer $installer::logger::Lang->printf("ERROR: could not compress %s\n", $filename); 281c9b362f6SAndre Fischer } 282c9b362f6SAndre Fischer else 283c9b362f6SAndre Fischer { 284c9b362f6SAndre Fischer unlink($filename); 285c9b362f6SAndre Fischer } 286c9b362f6SAndre Fischer } 287c9b362f6SAndre Fischer } 288c9b362f6SAndre Fischer elsif ($command eq "uncompress") 289c9b362f6SAndre Fischer { 290c9b362f6SAndre Fischer my ($source_name, $destination_name) = ($operation->[1], $operation->[2]); 291c9b362f6SAndre Fischer if ($CompressionMethod eq "bzip2") 292c9b362f6SAndre Fischer { 293c9b362f6SAndre Fischer $source_name .= ".bz2"; 294c9b362f6SAndre Fischer } 295c9b362f6SAndre Fischer $installer::logger::Lang->printf("uncompressing %s to %s\n", $source_name, $destination_name); 296c9b362f6SAndre Fischer 297c9b362f6SAndre Fischer my $destination_base_name = basename($destination_name); 298c9b362f6SAndre Fischer 299c9b362f6SAndre Fischer if ( ! $DryRun) 300c9b362f6SAndre Fischer { 301c9b362f6SAndre Fischer my $result = 0; 302c9b362f6SAndre Fischer if ($CompressionMethod eq "bzip2") 303c9b362f6SAndre Fischer { 304c9b362f6SAndre Fischer $result = IO::Uncompress::Bunzip2::bunzip2($source_name => $destination_name); 305c9b362f6SAndre Fischer } 306c9b362f6SAndre Fischer if ($result == 0) 307c9b362f6SAndre Fischer { 308c9b362f6SAndre Fischer $installer::logger::Lang->printf("ERROR: failed to extract content of '%s' from '%s'\n", 309c9b362f6SAndre Fischer $destination_name, $source_name); 310c9b362f6SAndre Fischer return 0; 311c9b362f6SAndre Fischer } 312c9b362f6SAndre Fischer } 313c9b362f6SAndre Fischer } 314c9b362f6SAndre Fischer 315c9b362f6SAndre Fischer else 316c9b362f6SAndre Fischer { 317c9b362f6SAndre Fischer die "unknown operation $command\n"; 318c9b362f6SAndre Fischer } 319c9b362f6SAndre Fischer } 320c9b362f6SAndre Fischer 321c9b362f6SAndre Fischer return 1; 322c9b362f6SAndre Fischer} 323c9b362f6SAndre Fischer 324c9b362f6SAndre Fischer 325c9b362f6SAndre Fischer 326c9b362f6SAndre Fischersub GetOperationCount ($) 327c9b362f6SAndre Fischer{ 328c9b362f6SAndre Fischer my ($self) = @_; 329c9b362f6SAndre Fischer return scalar @{$self->{'operations'}}; 330c9b362f6SAndre Fischer} 331c9b362f6SAndre Fischer 332c9b362f6SAndre Fischer 333c9b362f6SAndre Fischer1; 334