1 #*************************************************************************
3 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 # Copyright 2008 by Sun Microsystems, Inc.
7 # OpenOffice.org - a multi-platform office productivity suite
9 # $RCSfile: archivefiles.pm,v $
13 # This file is part of OpenOffice.org.
15 # OpenOffice.org is free software: you can redistribute it and/or modify
16 # it under the terms of the GNU Lesser General Public License version 3
17 # only, as published by the Free Software Foundation.
19 # OpenOffice.org is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 # GNU Lesser General Public License version 3 for more details
23 # (a copy is included in the LICENSE file that accompanied this code).
25 # You should have received a copy of the GNU Lesser General Public License
26 # version 3 along with OpenOffice.org. If not, see
27 # <http://www.openoffice.org/license.html>
28 # for a copy of the LGPLv3 License.
30 #*************************************************************************
32 package installer
::archivefiles
;
34 use Archive
::Zip
qw( :ERROR_CODES :CONSTANTS );
35 use installer
::converter
;
36 use installer
::existence
;
37 use installer
::exiter
;
39 use installer
::globals
;
40 use installer
::logger
;
41 use installer
::pathanalyzer
;
42 use installer
::systemactions
;
44 #################################################################
45 # Changing the name for files with flag RENAME_TO_LANGUAGE
46 #################################################################
48 sub put_language_into_name
50 my ( $oldname, $onelanguage ) = @_;
57 if ( $oldname =~ /^\s*(.*)(\..*?)\s*$/ ) # files with extension
68 $newname = $1 . "_" . $onelanguage . $2;
73 #################################################################
74 # Converting patchfiles string into array
75 #################################################################
77 sub get_patch_file_list
79 my ( $patchfilestring ) = @_;
81 $patchfilestring =~ s/^\s*\(?//;
82 $patchfilestring =~ s/\)?\s*$//;
83 $patchfilestring =~ s/^\s*\///;
84 $patchfilestring =~ s/^\s*\\//;
86 my $patchfilesarray = installer
::converter
::convert_stringlist_into_array_without_linebreak_and_quotes
(\
$patchfilestring, ",");
88 return $patchfilesarray;
91 #################################################################
92 # Analyzing files with flag ARCHIVE
93 #################################################################
95 sub resolving_archive_flag
97 my ($filesarrayref, $additionalpathsref, $languagestringref, $loggingdir) = @_;
99 if ( $installer::globals
::debug
) { installer
::logger
::debuginfo
("installer::archivefiles::resolving_archive_flag : $#{$filesarrayref} : $#{$additionalpathsref} : $$languagestringref : $loggingdir"); }
101 my @newallfilesarray = ();
103 my ($systemcall, $returnvalue, $infoline);
105 my $unziplistfile = $loggingdir . "unziplist_" . $installer::globals
::build
. "_" . $installer::globals
::compiler
. "_" . $$languagestringref . ".txt";
107 my $platformunzipdirbase = installer
::systemactions
::create_directories
("zip", $languagestringref);
108 push(@installer::globals
::removedirs
, $platformunzipdirbase);
110 installer
::logger
::include_header_into_logfile
("Files with flag ARCHIVE:");
112 my $repeat_unzip = 0;
115 for ( my $i = 0; $i <= $#{$filesarrayref}; $i++ )
117 if ( $repeat_unzip ) { $i--; } # decreasing the counter
119 my $onefile = ${$filesarrayref}[$i];
122 if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; }
124 if ( $styles =~ /\bARCHIVE\b/ ) # copying, unzipping and changing the file list
126 my $iscommonfile = 0;
127 my $sourcepath = $onefile->{'sourcepath'};
129 if ( $sourcepath =~ /\Q$installer::globals::separator\E\bcommon$installer::globals::productextension\Q$installer::globals::separator\E/ ) # /common/ or /common.pro/
134 my $use_internal_rights = 0;
135 if ( $styles =~ /\bUSE_INTERNAL_RIGHTS\b/ ) { $use_internal_rights = 1; } # using the rights used inside the zip file
137 my $rename_to_language = 0;
138 if ( $styles =~ /\bRENAME_TO_LANGUAGE\b/ ) { $rename_to_language = 1; } # special handling for renamed files (scriptitems.pm)
140 # mechanism to select files from an archive files
141 my $select_files = 0;
142 my $selectlistfiles = "";
144 if ( $onefile->{'Selectfiles'} )
147 $selectlistfiles = get_patch_file_list
( $onefile->{'Selectfiles'} );
148 $infoline = "Selected file list defined at file: $onefile->{'Name'} :\n";
149 push( @installer::globals
::logfileinfo
, $infoline);
150 for ( my $k = 0; $k <= $#{$selectlistfiles}; $k++ )
152 $infoline = "\"${$selectlistfiles}[$k]\"\n";
153 push( @installer::globals
::logfileinfo
, $infoline);
157 if ( $onefile->{'Selectfiles'} ) { $onefile->{'Selectfiles'} = ""; } # Selected files list no longer required
159 # mechanism to define patch files inside an archive files
160 my $select_patch_files = 0;
161 my $patchlistfiles = "";
162 my @keptpatchflags = ();
163 if (( $styles =~ /\bPATCH\b/ ) && ( $onefile->{'Patchfiles'} ) && ( $installer::globals
::patch
))
165 $select_patch_files = 1; # special handling if a Patchlist is defined
166 $patchlistfiles = get_patch_file_list
( $onefile->{'Patchfiles'} );
167 $infoline = "Patch file list defined at file: $onefile->{'Name'} :\n";
168 push( @installer::globals
::logfileinfo
, $infoline);
169 for ( my $k = 0; $k <= $#{$patchlistfiles}; $k++ )
171 $infoline = "\"${$patchlistfiles}[$k]\"\n";
172 push( @installer::globals
::logfileinfo
, $infoline);
176 if ( $onefile->{'Patchfiles'} ) { $onefile->{'Patchfiles'} = ""; } # Patch file list no longer required
178 # creating directories
180 my $onelanguage = $onefile->{'specificlanguage'};
182 # files without language into directory "00"
184 if ($onelanguage eq "") { $onelanguage = "00"; }
188 # if ($iscommonfile) { $unzipdir = $commonunzipdirbase . $installer::globals::separator . $onelanguage . $installer::globals::separator; }
189 # else { $unzipdir = $platformunzipdirbase . $installer::globals::separator . $onelanguage . $installer::globals::separator; }
191 $unzipdir = $platformunzipdirbase . $installer::globals
::separator
. $onelanguage . $installer::globals
::separator
;
193 installer
::systemactions
::create_directory
($unzipdir); # creating language specific subdirectories
195 my $onefilename = $onefile->{'Name'};
196 $onefilename =~ s/\./\_/g; # creating new directory name
197 $onefilename =~ s/\//\_
/g; # only because of /letter
/fontunxpsprint
.zip
, the only zip file with path
198 $unzipdir = $unzipdir . $onefilename . $installer::globals
::separator
;
200 if ( $installer::globals
::dounzip
) { installer
::systemactions
::create_directory
($unzipdir); } # creating subdirectories with the names of the zipfiles
202 my $zip = Archive
::Zip
->new();
203 if ( $zip->read($sourcepath) != AZ_OK
)
205 $infoline = "ERROR: Could not unzip $sourcepath\n";
206 push( @installer::globals
::logfileinfo
, $infoline);
210 my $contains_dll = 0;
211 foreach my $member ( $zip->memberNames() )
214 if ( $member =~ /.dll\s*$/ ) { $contains_dll = 1; }
217 if (! ( $counter > 0 )) # the zipfile is empty
219 $infoline = "ERROR: Could not unzip $sourcepath\n";
220 push( @installer::globals
::logfileinfo
, $infoline);
225 if ( $installer::globals
::dounzip
) # really unpacking the files
227 if ( $zip->extractTree("", $unzipdir) != AZ_OK
) { installer
::exiter
::exit_program
("ERROR: $infoline", "resolving_archive_flag"); }
229 if (( $^O
=~ /cygwin/i ) && ( $contains_dll ))
231 # Make dll's executable
232 $systemcall = "cd $unzipdir; find . -name \\*.dll -exec chmod 775 \{\} \\\;";
233 $returnvalue = system($systemcall);
234 $infoline = "Systemcall: $systemcall\n";
235 push( @installer::globals
::logfileinfo
, $infoline);
239 $infoline = "ERROR: Could not execute \"$systemcall\"!\n";
240 push( @installer::globals
::logfileinfo
, $infoline);
244 if ( ! $installer::globals
::iswindowsbuild
)
246 # Setting unix rights to "775" for all created directories inside the package
248 $systemcall = "cd $unzipdir; find . -type d -exec chmod 775 \{\} \\\;";
249 $returnvalue = system($systemcall);
250 $infoline = "Systemcall: $systemcall\n";
251 push( @installer::globals
::logfileinfo
, $infoline);
255 $infoline = "ERROR: Could not execute \"$systemcall\"!\n";
256 push( @installer::globals
::logfileinfo
, $infoline);
261 my $zipfileref = \
@zipfile;
264 foreach my $zipname ( $zip->memberNames() )
266 # Format from Archive:::Zip :
268 # dir1/so7drawing.desktop
270 # some directories and files (from the help) start with "./simpress.idx"
272 $zipname =~ s/^\s*\.\///;
274 if ($installer::globals
::iswin
and $^O
=~ /MSWin/i) { $zipname =~ s/\//\\/g
; }
276 if ( $zipname =~ /\Q$installer::globals::separator\E\s*$/ ) # slash or backslash at the end characterizes a directory
278 $zipname = $zipname . "\n";
279 push(@
{$additionalpathsref}, $zipname);
287 # This is not needed, because the list of all directories for the
288 # epm list file is generated from the destination directories of the
289 # files included in the product!
294 %newfile = %{$onefile};
295 $newfile{'Name'} = $zipname;
296 my $destination = $onefile->{'destination'};
297 installer
::pathanalyzer
::get_path_from_fullqualifiedname
(\
$destination);
298 $newfile{'destination'} = $destination . $zipname;
299 $newfile{'sourcepath'} = $unzipdir . $zipname;
300 $newfile{'zipfilename'} = $onefile->{'Name'};
301 $newfile{'zipfilesource'} = $onefile->{'sourcepath'};
302 $newfile{'zipfiledestination'} = $onefile->{'destination'};
304 if (( $use_internal_rights ) && ( ! $installer::globals
::iswin
))
306 my $value = sprintf("%o", (stat($newfile{'sourcepath'}))[2]);
307 $newfile{'UnixRights'} = substr($value, 3);
308 $infoline = "Setting unix rights for \"$newfile{'sourcepath'}\" to \"$newfile{'UnixRights'}\"\n";
309 push( @installer::globals
::logfileinfo
, $infoline);
314 if ( ! installer
::existence
::exists_in_array
($zipname,$selectlistfiles) )
316 $infoline = "Removing from ARCHIVE file $onefilename: $zipname\n";
317 push( @installer::globals
::logfileinfo
, $infoline);
318 next; # ignoring files, that are not included in $selectlistfiles
322 $infoline = "Keeping from ARCHIVE file $onefilename: $zipname\n";
323 push( @installer::globals
::logfileinfo
, $infoline);
324 push( @keptfiles, $zipname); # collecting all kept files
328 if ( $select_patch_files )
330 # Is this file listed in the Patchfile list?
331 # $zipname (filename including path in zip file has to be listed in patchfile list
333 if ( ! installer
::existence
::exists_in_array
($zipname,$patchlistfiles) )
335 $newfile{'Styles'} =~ s/\bPATCH\b//; # removing the flag PATCH
336 $newfile{'Styles'} =~ s/\,\s*\,/\,/;
337 $newfile{'Styles'} =~ s/\(\s*\,/\(/;
338 $newfile{'Styles'} =~ s/\,\s*\)/\)/;
339 # $infoline = "Removing PATCH flag from: $zipname\n";
340 # push( @installer::globals::logfileinfo, $infoline);
344 # $infoline = "Keeping PATCH flag at: $zipname\n";
345 # push( @installer::globals::logfileinfo, $infoline);
346 push( @keptpatchflags, $zipname); # collecting all PATCH flags
350 if ( $rename_to_language )
352 my $newzipname = put_language_into_name
($zipname, $onelanguage);
353 my $oldfilename = $unzipdir . $zipname;
354 my $newfilename = $unzipdir . $newzipname;
356 installer
::systemactions
::copy_one_file
($oldfilename, $newfilename);
358 $newfile{'Name'} = $newzipname;
359 $newfile{'destination'} = $destination . $newzipname;
360 $newfile{'sourcepath'} = $unzipdir . $newzipname;
362 $infoline = "RENAME_TO_LANGUAGE: Using $newzipname instead of $zipname!\n";
363 push( @installer::globals
::logfileinfo
, $infoline);
366 my $sourcefiletest = $unzipdir . $zipname;
367 if ( ! -f
$sourcefiletest )
369 $infoline = "ATTENTION: Unzip failed for $sourcefiletest!\n";
370 push( @installer::globals
::logfileinfo
, $infoline);
374 # only adding the new line into the files array, if not in repeat modus
376 if ( ! $repeat_unzip ) { push(@newallfilesarray, \
%newfile); }
380 # Comparing the content of @keptfiles and $selectlistfiles
381 # Do all files from the list of selected files are stored in @keptfiles ?
382 # @keptfiles contains only files included in $selectlistfiles. But are all
383 # files from $selectlistfiles included in @keptfiles?
387 my $number = $#{$selectlistfiles} + 1;
388 $infoline = "SELECTLIST: Number of files in file selection list: $number\n";
389 push( @installer::globals
::logfileinfo
, $infoline);
390 $number = $#keptfiles + 1;
391 $infoline = "SELECTLIST: Number of kept files: $number\n";
392 push( @installer::globals
::logfileinfo
, $infoline);
394 for ( my $k = 0; $k <= $#keptfiles; $k++ )
396 $infoline = "KEPT FILES: $keptfiles[$k]\n";
397 push( @installer::globals
::logfileinfo
, $infoline);
400 my @warningfiles = ();
402 for ( my $k = 0; $k <= $#{$selectlistfiles}; $k++ )
404 if ( ! installer
::existence
::exists_in_array
(${$selectlistfiles}[$k],\
@keptfiles) )
406 push(@warningfiles, ${$selectlistfiles}[$k]);
410 for ( my $k = 0; $k <= $#warningfiles; $k++ )
412 $infoline = "WARNING: $warningfiles[$k] not included in install set (does not exist in zip file)!\n";
413 push( @installer::globals
::logfileinfo
, $infoline);
418 # Comparing the content of @keptpatchflags and $patchlistfiles
419 # Do all files from the patch list have a PATCH flag ?
420 # @keptpatchflags contains only files included in $patchlistfiles. But are all
421 # files from $patchlistfiles included in @keptpatchflags?
423 if ( $select_patch_files )
425 my $number = $#{$patchlistfiles} + 1;
426 $infoline = "PATCHLIST: Number of files in patch list: $number\n";
427 push( @installer::globals
::logfileinfo
, $infoline);
428 $number = $#keptpatchflags + 1;
429 $infoline = "PATCHLIST: Number of kept PATCH flags: $number\n";
430 push( @installer::globals
::logfileinfo
, $infoline);
432 for ( my $k = 0; $k <= $#keptpatchflags; $k++ )
434 $infoline = "KEPT PATCH FLAGS: $keptpatchflags[$k]\n";
435 push( @installer::globals
::logfileinfo
, $infoline);
438 my @warningfiles = ();
440 for ( my $k = 0; $k <= $#{$patchlistfiles}; $k++ )
442 if ( ! installer
::existence
::exists_in_array
(${$patchlistfiles}[$k],\
@keptpatchflags) )
444 push(@warningfiles, ${$patchlistfiles}[$k]);
448 for ( my $k = 0; $k <= $#warningfiles; $k++ )
450 $infoline = "WARNING: $warningfiles[$k] did not keep PATCH flag (does not exist in zip file)!\n";
451 push( @installer::globals
::logfileinfo
, $infoline);
457 installer
::logger
::print_warning
( "Repeating to unpack $sourcepath! \n" );
458 $infoline = "ATTENTION: Repeating to unpack $sourcepath !\n";
459 push( @installer::globals
::logfileinfo
, $infoline);
463 if ( $maxcounter == 5 ) # exiting the program
465 installer
::exiter
::exit_program
("ERROR: Failed to unzip $sourcepath !", "resolving_archive_flag");
470 $infoline = "Info: $sourcepath unpacked without problems !\n";
471 push( @installer::globals
::logfileinfo
, $infoline);
477 else # nothing to do here, no zipped file (no ARCHIVE flag)
479 push(@newallfilesarray, $onefile);
484 push( @installer::globals
::logfileinfo
, $infoline);
486 return \
@newallfilesarray;