1#*************************************************************************
2#
3# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4#
5# Copyright 2000, 2010 Oracle and/or its affiliates.
6#
7# OpenOffice.org - a multi-platform office productivity suite
8#
9# This file is part of OpenOffice.org.
10#
11# OpenOffice.org is free software: you can redistribute it and/or modify
12# it under the terms of the GNU Lesser General Public License version 3
13# only, as published by the Free Software Foundation.
14#
15# OpenOffice.org is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18# GNU Lesser General Public License version 3 for more details
19# (a copy is included in the LICENSE file that accompanied this code).
20#
21# You should have received a copy of the GNU Lesser General Public License
22# version 3 along with OpenOffice.org.  If not, see
23# <http://www.openoffice.org/license.html>
24# for a copy of the LGPLv3 License.
25#
26#*************************************************************************
27
28package installer::simplepackage;
29
30# use Archive::Zip qw( :ERROR_CODES :CONSTANTS );
31use Cwd;
32use File::Copy;
33use installer::download;
34use installer::exiter;
35use installer::globals;
36use installer::logger;
37use installer::strip;
38use installer::systemactions;
39use installer::worker;
40
41####################################################
42# Checking if the simple packager is required.
43# This can be achieved by setting the global
44# variable SIMPLE_PACKAGE in *.lst file or by
45# setting the environment variable SIMPLE_PACKAGE.
46####################################################
47
48sub check_simple_packager_project
49{
50	my ( $allvariables ) = @_;
51
52	if (( $installer::globals::packageformat eq "installed" ) ||
53		( $installer::globals::packageformat eq "archive" ))
54	{
55		$installer::globals::is_simple_packager_project = 1;
56		$installer::globals::patch_user_dir = 1;
57	}
58	elsif( $installer::globals::packageformat eq "dmg" )
59	{
60		$installer::globals::is_simple_packager_project = 1;
61	}
62}
63
64####################################################
65# Detecting the directory with extensions
66####################################################
67
68sub get_extensions_dir
69{
70	my ( $subfolderdir ) = @_;
71
72	my $extensiondir = $subfolderdir . $installer::globals::separator;
73	if ( $installer::globals::officedirhostname ne "" ) { $extensiondir = $extensiondir . $installer::globals::officedirhostname . $installer::globals::separator; }
74	my $extensionsdir = $extensiondir . "share" . $installer::globals::separator . "extensions";
75	my $preregdir = $extensiondir . "share" . $installer::globals::separator . "prereg" . $installer::globals::separator . "bundled";
76
77	return ( $extensionsdir, $preregdir );
78}
79
80####################################################
81# Registering extensions
82####################################################
83
84sub register_extensions
85{
86	my ($officedir, $languagestringref, $preregdir) = @_;
87
88	my $infoline = "";
89
90	if ( $preregdir eq "" )
91	{
92		$infoline = "ERROR: Failed to determine directory \"prereg\" for extension registration! Please check your installation set.\n";
93		push( @installer::globals::logfileinfo, $infoline);
94		installer::exiter::exit_program($infoline, "register_extensions");
95	}
96
97	my $programdir = $officedir . $installer::globals::separator;
98	if ( $installer::globals::officedirhostname ne "" ) { $programdir = $programdir . $installer::globals::officedirhostname . $installer::globals::separator; }
99	$programdir = $programdir . "program";
100
101	my $from = cwd();
102	chdir($programdir);
103
104	my $unopkgfile = $installer::globals::unopkgfile;
105
106	my $unopkgexists = 1;
107	if (( $installer::globals::languagepack ) && ( ! -f $unopkgfile ))
108	{
109		$unopkgexists = 0;
110		$infoline = "Language packs do not contain unopkg!\n";
111		push( @installer::globals::logfileinfo, $infoline);
112	}
113
114	if ( ! -f $unopkgfile )
115	{
116		$unopkgexists = 0;
117		$infoline = "Info: File $unopkgfile does not exist! Extensions cannot be registered.\n";
118		push( @installer::globals::logfileinfo, $infoline);
119	}
120
121	if ( $unopkgexists )
122	{
123		my $currentdir = cwd();
124		print "... current dir: $currentdir ...\n";
125		$infoline = "Current dir: $currentdir\n";
126		push( @installer::globals::logfileinfo, $infoline);
127
128		if ( ! -f $unopkgfile ) { installer::exiter::exit_program("ERROR: $unopkgfile not found!", "register_extensions"); }
129
130		my $systemcall = $unopkgfile . " sync --verbose" . " -env:UNO_JAVA_JFW_ENV_JREHOME=true 2\>\&1 |";
131
132		print "... $systemcall ...\n";
133
134		$infoline = "Systemcall: $systemcall\n";
135		push( @installer::globals::logfileinfo, $infoline);
136
137		my @unopkgoutput = ();
138
139		open (UNOPKG, $systemcall);
140		while (<UNOPKG>)
141		{
142			my $lastline = $_;
143			push(@unopkgoutput, $lastline);
144		}
145		close (UNOPKG);
146
147		my $returnvalue = $?;	# $? contains the return value of the systemcall
148
149		if ($returnvalue)
150		{
151			# Writing content of @unopkgoutput only in the error case into the log file. Sometimes it
152			# contains strings like "Error" even in the case of success. This causes a packaging error
153			# when the log file is analyzed at the end, even if there is no real error.
154			for ( my $j = 0; $j <= $#unopkgoutput; $j++ ) { push( @installer::globals::logfileinfo, "$unopkgoutput[$j]"); }
155
156			$infoline = "ERROR: Could not execute \"$systemcall\"!\nExitcode: '$returnvalue'\n";
157			push( @installer::globals::logfileinfo, $infoline);
158			installer::exiter::exit_program("ERROR: $systemcall failed!", "register_extensions");
159		}
160		else
161		{
162			$infoline = "Success: Executed \"$systemcall\" successfully!\n";
163			push( @installer::globals::logfileinfo, $infoline);
164		}
165	}
166
167	chdir($from);
168}
169
170########################################################################
171# Getting the translation file for the Mac Language Pack installer
172########################################################################
173
174sub get_mac_translation_file
175{
176	my $translationfilename = $installer::globals::maclangpackfilename;
177	# my $translationfilename = $installer::globals::idtlanguagepath . $installer::globals::separator . $installer::globals::maclangpackfilename;
178	# if ( $installer::globals::unicodensis ) { $translationfilename = $translationfilename . ".uulf"; }
179	# else { $translationfilename = $translationfilename . ".mlf"; }
180	if ( ! -f $translationfilename ) { installer::exiter::exit_program("ERROR: Could not find language file $translationfilename!", "get_mac_translation_file"); }
181	my $translationfile = installer::files::read_file($translationfilename);
182
183	my $infoline = "Reading translation file: $translationfilename\n";
184	push( @installer::globals::logfileinfo, $infoline);
185
186	return $translationfile;
187}
188
189##################################################################
190# Collecting all identifier from ulf file
191##################################################################
192
193sub get_identifier
194{
195	my ( $translationfile ) = @_;
196
197	my @identifier = ();
198
199	for ( my $i = 0; $i <= $#{$translationfile}; $i++ )
200	{
201		my $oneline = ${$translationfile}[$i];
202
203		if ( $oneline =~ /^\s*\[(.+)\]\s*$/ )
204		{
205			my $identifier = $1;
206			push(@identifier, $identifier);
207		}
208	}
209
210	return \@identifier;
211}
212
213##############################################################
214# Returning the complete block in all languages
215# for a specified string
216##############################################################
217
218sub get_language_block_from_language_file
219{
220	my ($searchstring, $languagefile) = @_;
221
222	my @language_block = ();
223
224	for ( my $i = 0; $i <= $#{$languagefile}; $i++ )
225	{
226		if ( ${$languagefile}[$i] =~ /^\s*\[\s*$searchstring\s*\]\s*$/ )
227		{
228			my $counter = $i;
229
230			push(@language_block, ${$languagefile}[$counter]);
231			$counter++;
232
233			while (( $counter <= $#{$languagefile} ) && (!( ${$languagefile}[$counter] =~ /^\s*\[/ )))
234			{
235				push(@language_block, ${$languagefile}[$counter]);
236				$counter++;
237			}
238
239			last;
240		}
241	}
242
243	return \@language_block;
244}
245
246##############################################################
247# Returning a specific language string from the block
248# of all translations
249##############################################################
250
251sub get_language_string_from_language_block
252{
253	my ($language_block, $language) = @_;
254
255	my $newstring = "";
256
257	for ( my $i = 0; $i <= $#{$language_block}; $i++ )
258	{
259		if ( ${$language_block}[$i] =~ /^\s*$language\s*\=\s*\"(.*)\"\s*$/ )
260		{
261			$newstring = $1;
262			last;
263		}
264	}
265
266	if ( $newstring eq "" )
267	{
268		$language = "en-US"; 	# defaulting to english
269
270		for ( my $i = 0; $i <= $#{$language_block}; $i++ )
271		{
272			if ( ${$language_block}[$i] =~ /^\s*$language\s*\=\s*\"(.*)\"\s*$/ )
273			{
274				$newstring = $1;
275				last;
276			}
277		}
278	}
279
280	return $newstring;
281}
282
283########################################################################
284# Localizing the script for the Mac Language Pack installer
285########################################################################
286
287sub localize_scriptfile
288{
289	my ($scriptfile, $translationfile, $languagestringref) = @_;
290
291	# my $translationfile = get_mac_translation_file();
292
293	my $onelanguage = $$languagestringref;
294	if ( $onelanguage =~ /^\s*(.*?)_/ ) { $onelanguage = $1; }
295
296	# Analyzing the ulf file, collecting all Identifier
297	my $allidentifier = get_identifier($translationfile);
298
299	for ( my $i = 0; $i <= $#{$allidentifier}; $i++ )
300	{
301		my $identifier = ${$allidentifier}[$i];
302		my $language_block = get_language_block_from_language_file($identifier, $translationfile);
303		my $newstring = get_language_string_from_language_block($language_block, $onelanguage);
304
305		# removing mask
306		$newstring =~ s/\\\'/\'/g;
307
308		replace_one_variable_in_shellscript($scriptfile, $newstring, $identifier);
309	}
310}
311
312#################################################################################
313# Replacing one variable in Mac shell script
314#################################################################################
315
316sub replace_one_variable_in_shellscript
317{
318	my ($scriptfile, $variable, $searchstring) = @_;
319
320	for ( my $i = 0; $i <= $#{$scriptfile}; $i++ )
321	{
322		${$scriptfile}[$i] =~ s/\[$searchstring\]/$variable/g;
323	}
324}
325
326#############################################
327# Replacing variables in Mac shell script
328#############################################
329
330sub replace_variables_in_scriptfile
331{
332	my ($scriptfile, $volume_name, $volume_name_app, $allvariables) = @_;
333
334	replace_one_variable_in_shellscript($scriptfile, $volume_name, "FULLPRODUCTNAME" );
335	replace_one_variable_in_shellscript($scriptfile, $volume_name_app, "FULLAPPPRODUCTNAME" );
336	replace_one_variable_in_shellscript($scriptfile, $allvariables->{'PRODUCTNAME'}, "PRODUCTNAME" );
337	replace_one_variable_in_shellscript($scriptfile, $allvariables->{'PRODUCTVERSION'}, "PRODUCTVERSION" );
338
339	my $scriptname = lc($allvariables->{'PRODUCTNAME'}) . "\.script";
340	if ( $allvariables->{'PRODUCTNAME'} eq "OpenOffice.org" ) { $scriptname = "org.openoffice.script"; }
341
342	replace_one_variable_in_shellscript($scriptfile, $scriptname, "SEARCHSCRIPTNAME" );
343}
344
345#############################################
346# Creating the "simple" package.
347# "zip" for Windows
348# "tar.gz" for all other platforms
349# additionally "dmg" on Mac OS X
350#############################################
351
352sub create_package
353{
354	my ( $installdir, $archivedir, $packagename, $allvariables, $includepatharrayref, $languagestringref, $format ) = @_;
355
356    installer::logger::print_message( "... creating $installer::globals::packageformat file ...\n" );
357    installer::logger::include_header_into_logfile("Creating $installer::globals::packageformat file:");
358
359	# moving dir into temporary directory
360	my $pid = $$; # process id
361	my $tempdir = $installdir . "_temp" . "." . $pid;
362	my $systemcall = "";
363	my $from = "";
364	my $makesystemcall = 1;
365	my $return_to_start = 0;
366	installer::systemactions::rename_directory($installdir, $tempdir);
367
368	# creating new directory with original name
369	installer::systemactions::create_directory($archivedir);
370
371	my $archive = $archivedir . $installer::globals::separator . $packagename . $format;
372
373	if ( $archive =~ /zip$/ )
374	{
375		$from = cwd();
376		$return_to_start = 1;
377		chdir($tempdir);
378		$systemcall = "$installer::globals::zippath -qr $archive .";
379
380		# Using Archive::Zip fails because of very long path names below "share/uno_packages/cache"
381		# my $packzip = Archive::Zip->new();
382		# $packzip->addTree(".");	# after changing into $tempdir
383		# $packzip->writeToFileNamed($archive);
384		# $makesystemcall = 0;
385	}
386 	elsif ( $archive =~ /dmg$/ )
387	{
388		my $folder = (( -l "$tempdir/$packagename/Applications" ) or ( -l "$tempdir/$packagename/opt" )) ? $packagename : "\.";
389
390		if ( $allvariables->{'PACK_INSTALLED'} ) {
391		    $folder = $packagename;
392		}
393
394		# my $volume_name = $allvariables->{'PRODUCTNAME'} . ' ' . $allvariables->{'PRODUCTVERSION'}; # Adding PRODUCTVERSION makes this difficult to maintain!
395		my $volume_name = $allvariables->{'PRODUCTNAME'};
396		my $volume_name_classic = $allvariables->{'PRODUCTNAME'} . ' ' . $allvariables->{'PRODUCTVERSION'};
397		my $volume_name_classic_app = $volume_name;  # "app" should not contain version number
398		# $volume_name = $volume_name . ' ' . $allvariables->{'PRODUCTEXTENSION'} if $allvariables->{'PRODUCTEXTENSION'}; # Adding PRODUCTEXTENSION makes this difficult to maintain!
399		$volume_name_classic = $volume_name_classic . ' ' . $allvariables->{'PRODUCTEXTENSION'} if $allvariables->{'PRODUCTEXTENSION'};
400		$volume_name_classic_app = $volume_name_classic_app . ' ' . $allvariables->{'PRODUCTEXTENSION'} if $allvariables->{'PRODUCTEXTENSION'};
401		if ( $allvariables->{'DMG_VOLUMEEXTENSION'} ) {
402		    $volume_name = $volume_name . ' ' . $allvariables->{'DMG_VOLUMEEXTENSION'};
403		    $volume_name_classic = $volume_name_classic . ' ' . $allvariables->{'DMG_VOLUMEEXTENSION'};
404		    $volume_name_classic_app = $volume_name_classic_app . ' ' . $allvariables->{'DMG_VOLUMEEXTENSION'};
405		}
406
407		my $sla = 'sla.r';
408		my $ref = "";
409
410		if ( ! $allvariables->{'HIDELICENSEDIALOG'} )
411		{
412			installer::scriptitems::get_sourcepath_from_filename_and_includepath( \$sla, $includepatharrayref, 0);
413		}
414
415		my $localtempdir = $tempdir;
416
417		if (( $installer::globals::languagepack ) || ( $installer::globals::patch ))
418		{
419			$localtempdir = "$tempdir/$packagename";
420			if ( $installer::globals::languagepack )
421			{
422				$volume_name = "$volume_name Language Pack";
423				$volume_name_classic = "$volume_name_classic Language Pack";
424				$volume_name_classic_app = "$volume_name_classic_app Language Pack";
425			}
426			if ( $installer::globals::patch )
427			{
428				$volume_name = "$volume_name Patch";
429				$volume_name_classic = "$volume_name_classic Patch";
430				$volume_name_classic_app = "$volume_name_classic_app Patch";
431			}
432
433			# Create tar ball named tarball.tar.bz2
434			# my $appfolder = $localtempdir . "/" . $volume_name . "\.app";
435			my $appfolder = $localtempdir . "/" . $volume_name_classic_app . "\.app";
436			my $contentsfolder = $appfolder . "/Contents";
437			my $tarballname = "tarball.tar.bz2";
438
439			my $localfrom = cwd();
440			chdir $appfolder;
441
442			$systemcall = "tar -cjf $tarballname Contents/";
443
444			print "... $systemcall ...\n";
445			my $localreturnvalue = system($systemcall);
446			$infoline = "Systemcall: $systemcall\n";
447			push( @installer::globals::logfileinfo, $infoline);
448
449			if ($localreturnvalue)
450			{
451				$infoline = "ERROR: Could not execute \"$systemcall\"!\n";
452				push( @installer::globals::logfileinfo, $infoline);
453			}
454			else
455			{
456				$infoline = "Success: Executed \"$systemcall\" successfully!\n";
457				push( @installer::globals::logfileinfo, $infoline);
458			}
459
460			my $sourcefile = $appfolder . "/" . $tarballname;
461			my $destfile = $contentsfolder . "/" . $tarballname;
462
463			installer::systemactions::remove_complete_directory($contentsfolder);
464			installer::systemactions::create_directory($contentsfolder);
465
466			installer::systemactions::copy_one_file($sourcefile, $destfile);
467			unlink($sourcefile);
468
469			# Copy two files into installation set next to the tar ball
470			# 1. "osx_install.applescript"
471			# 2 "OpenOffice.org Languagepack"
472
473			my $scriptrealfilename = "osx_install.applescript";
474			my $scriptfilename = "";
475			if ( $installer::globals::languagepack ) { $scriptfilename = "osx_install_languagepack.applescript"; }
476			if ( $installer::globals::patch ) { $scriptfilename = "osx_install_patch.applescript"; }
477			my $scripthelpersolverfilename = "mac_install.script";
478			# my $scripthelperrealfilename = $volume_name;
479			my $scripthelperrealfilename = $volume_name_classic_app;
480			my $translationfilename = $installer::globals::macinstallfilename;
481
482			# Finding both files in solver
483
484			my $scriptref = installer::scriptitems::get_sourcepath_from_filename_and_includepath( \$scriptfilename, $includepatharrayref, 0);
485			if ($$scriptref eq "") { installer::exiter::exit_program("ERROR: Could not find Apple script $scriptfilename!", "create_package"); }
486			my $scripthelperref = installer::scriptitems::get_sourcepath_from_filename_and_includepath( \$scripthelpersolverfilename, $includepatharrayref, 0);
487			if ($$scripthelperref eq "") { installer::exiter::exit_program("ERROR: Could not find Apple script $scripthelpersolverfilename!", "create_package"); }
488			my $translationfileref = installer::scriptitems::get_sourcepath_from_filename_and_includepath( \$translationfilename, $includepatharrayref, 0);
489			if ($$translationfileref eq "") { installer::exiter::exit_program("ERROR: Could not find Apple script translation file $translationfilename!", "create_package"); }
490
491			$scriptfilename = $contentsfolder . "/" . $scriptrealfilename;
492			$scripthelperrealfilename = $contentsfolder . "/" . $scripthelperrealfilename;
493
494			installer::systemactions::copy_one_file($$scriptref, $scriptfilename);
495			installer::systemactions::copy_one_file($$scripthelperref, $scripthelperrealfilename);
496
497			# Replacing variables in script $scriptfilename
498			# Localizing script $scriptfilename
499			my $scriptfilecontent = installer::files::read_file($scriptfilename);
500			my $translationfilecontent = installer::files::read_file($$translationfileref);
501			localize_scriptfile($scriptfilecontent, $translationfilecontent, $languagestringref);
502			# replace_variables_in_scriptfile($scriptfilecontent, $volume_name, $allvariables);
503			replace_variables_in_scriptfile($scriptfilecontent, $volume_name_classic, $volume_name_classic_app, $allvariables);
504			installer::files::save_file($scriptfilename, $scriptfilecontent);
505
506			$systemcall = "chmod 775 " . "\"" . $scriptfilename . "\"";
507			system($systemcall);
508			$systemcall = "chmod 775 " . "\"" . $scripthelperrealfilename . "\"";
509			system($systemcall);
510
511			# Copy also Info.plist and icon file
512			# Finding both files in solver
513			my $iconfile = "ooo3_installer.icns";
514			my $iconfileref = installer::scriptitems::get_sourcepath_from_filename_and_includepath( \$iconfile, $includepatharrayref, 0);
515			if ($$iconfileref eq "") { installer::exiter::exit_program("ERROR: Could not find Apple script icon file $iconfile!", "create_package"); }
516			my $subdir = $contentsfolder . "/" . "Resources";
517			if ( ! -d $subdir ) { installer::systemactions::create_directory($subdir); }
518			$destfile = $subdir . "/" . $iconfile;
519			installer::systemactions::copy_one_file($$iconfileref, $destfile);
520
521			my $infoplistfile = "Info.plist.langpack";
522			my $installname = "Info.plist";
523			my $infoplistfileref = installer::scriptitems::get_sourcepath_from_filename_and_includepath( \$infoplistfile, $includepatharrayref, 0);
524			if ($$infoplistfileref eq "") { installer::exiter::exit_program("ERROR: Could not find Apple script Info.plist: $infoplistfile!", "create_package"); }
525			$destfile = $contentsfolder . "/" . $installname;
526			installer::systemactions::copy_one_file($$infoplistfileref, $destfile);
527
528			# Replacing variables in Info.plist
529			$scriptfilecontent = installer::files::read_file($destfile);
530			# replace_one_variable_in_shellscript($scriptfilecontent, $volume_name, "FULLPRODUCTNAME" );
531			replace_one_variable_in_shellscript($scriptfilecontent, $volume_name_classic_app, "FULLAPPPRODUCTNAME" ); # OpenOffice.org Language Pack
532			installer::files::save_file($destfile, $scriptfilecontent);
533
534			chdir $localfrom;
535		}
536
537		$systemcall = "cd $localtempdir && hdiutil makehybrid -hfs -hfs-openfolder $folder $folder -hfs-volume-name \"$volume_name\" -ov -o $installdir/tmp && hdiutil convert -ov -format UDZO $installdir/tmp.dmg -o $archive && ";
538        if (( $ref ne "" ) && ( $$ref ne "" )) {
539			$systemcall .= "hdiutil unflatten $archive && Rez -a $$ref -o $archive && hdiutil flatten $archive &&";
540		}
541		$systemcall .= "rm -f $installdir/tmp.dmg";
542	}
543	else
544	{
545		# getting the path of the getuid.so (only required for Solaris and Linux)
546		my $getuidlibrary = "";
547		my $ldpreloadstring = "";
548		if (( $installer::globals::issolarisbuild ) || ( $installer::globals::islinuxbuild ))
549		{
550			$getuidlibrary = installer::download::get_path_for_library($includepatharrayref);
551			if ( $getuidlibrary ne "" ) { $ldpreloadstring = "LD_PRELOAD=" . $getuidlibrary; }
552		}
553
554		$systemcall = "cd $tempdir; $ldpreloadstring tar -cf - . | gzip > $archive";
555	}
556
557	if ( $makesystemcall )
558	{
559		print "... $systemcall ...\n";
560		my $returnvalue = system($systemcall);
561		my $infoline = "Systemcall: $systemcall\n";
562		push( @installer::globals::logfileinfo, $infoline);
563
564		if ($returnvalue)
565		{
566			$infoline = "ERROR: Could not execute \"$systemcall\"!\n";
567			push( @installer::globals::logfileinfo, $infoline);
568		}
569		else
570		{
571			$infoline = "Success: Executed \"$systemcall\" successfully!\n";
572			push( @installer::globals::logfileinfo, $infoline);
573		}
574	}
575
576	if ( $return_to_start ) { chdir($from); }
577
578	print "... removing $tempdir ...\n";
579	installer::systemactions::remove_complete_directory($tempdir);
580}
581
582####################################################
583# Main method for creating the simple package
584# installation sets
585####################################################
586
587sub create_simple_package
588{
589	my ( $filesref, $dirsref, $scpactionsref, $linksref, $unixlinksref, $loggingdir, $languagestringref, $shipinstalldir, $allsettingsarrayref, $allvariables, $includepatharrayref ) = @_;
590
591	# Creating directories
592
593	my $current_install_number = "";
594	my $infoline = "";
595
596	installer::logger::print_message( "... creating installation directory ...\n" );
597	installer::logger::include_header_into_logfile("Creating installation directory");
598
599	$installer::globals::csp_installdir = installer::worker::create_installation_directory($shipinstalldir, $languagestringref, \$current_install_number);
600	$installer::globals::csp_installlogdir = installer::systemactions::create_directory_next_to_directory($installer::globals::csp_installdir, "log");
601
602	my $installdir = $installer::globals::csp_installdir;
603	my $installlogdir = $installer::globals::csp_installlogdir;
604
605	# Setting package name (similar to the download name)
606	my $packagename = "";
607
608	if ( $installer::globals::packageformat eq "archive"  ||
609		$installer::globals::packageformat eq "dmg" )
610	{
611		$installer::globals::csp_languagestring = $$languagestringref;
612
613		my $locallanguage = $installer::globals::csp_languagestring;
614
615		if ( $allvariables->{'OOODOWNLOADNAME'} )
616		{
617			$packagename = installer::download::set_download_filename(\$locallanguage, $allvariables);
618		}
619		else
620		{
621			$downloadname = installer::ziplist::getinfofromziplist($allsettingsarrayref, "downloadname");
622			if ( $installer::globals::languagepack ) { $downloadname = installer::ziplist::getinfofromziplist($allsettingsarrayref, "langpackdownloadname"); }
623			if ( $installer::globals::patch ) { $downloadname = installer::ziplist::getinfofromziplist($allsettingsarrayref, "patchdownloadname"); }
624			$packagename = installer::download::resolve_variables_in_downloadname($allvariables, $$downloadname, \$locallanguage);
625		}
626	}
627
628    # Work around Windows problems with long pathnames (see issue 50885) by
629    # putting the to-be-archived installation tree into the temp directory
630    # instead of the module output tree (unless LOCALINSTALLDIR dictates
631    # otherwise, anyway); can be removed once issue 50885 is fixed:
632    my $tempinstalldir = $installdir;
633    if ( $installer::globals::iswindowsbuild &&
634         $installer::globals::packageformat eq "archive" &&
635         !$installer::globals::localinstalldirset )
636    {
637        $tempinstalldir = File::Temp::tempdir;
638    }
639
640	# Creating subfolder in installdir, which shall become the root of package or zip file
641	my $subfolderdir = "";
642	if ( $packagename ne "" ) { $subfolderdir = $tempinstalldir . $installer::globals::separator . $packagename; }
643	else { $subfolderdir = $tempinstalldir; }
644
645	if ( ! -d $subfolderdir ) { installer::systemactions::create_directory($subfolderdir); }
646
647	# Create directories, copy files and ScpActions
648
649	installer::logger::print_message( "... creating directories ...\n" );
650	installer::logger::include_header_into_logfile("Creating directories:");
651
652	for ( my $i = 0; $i <= $#{$dirsref}; $i++ )
653	{
654		my $onedir = ${$dirsref}[$i];
655
656		if ( $onedir->{'HostName'} )
657		{
658			my $destdir = $subfolderdir . $installer::globals::separator . $onedir->{'HostName'};
659
660			if ( ! -d $destdir )
661			{
662				if ( $^O =~ /cygwin/i ) # Cygwin performance check
663				{
664					$infoline = "Try to create directory $destdir\n";
665					push(@installer::globals::logfileinfo, $infoline);
666					# Directories in $dirsref are sorted and all parents were added -> "mkdir" works without parent creation!
667					if ( ! ( -d $destdir )) { mkdir($destdir, 0775); }
668				}
669				else
670				{
671					installer::systemactions::create_directory_structure($destdir);
672				}
673			}
674		}
675	}
676
677	# stripping files ?!
678	if (( $installer::globals::strip ) && ( ! $installer::globals::iswindowsbuild )) { installer::strip::strip_libraries($filesref, $languagestringref); }
679
680	# copy Files
681	installer::logger::print_message( "... copying files ...\n" );
682	installer::logger::include_header_into_logfile("Copying files:");
683
684	for ( my $i = 0; $i <= $#{$filesref}; $i++ )
685	{
686		my $onefile = ${$filesref}[$i];
687
688		if (( $onefile->{'Styles'} ) && ( $onefile->{'Styles'} =~ /\bBINARYTABLE_ONLY\b/ )) { next; }
689		if (( $installer::globals::patch ) && ( $onefile->{'Styles'} ) && ( ! ( $onefile->{'Styles'} =~ /\bPATCH\b/ ))) { next; }
690		if (( $installer::globals::patch ) && ( $installer::globals::packageformat eq "dmg" )) { push(@installer::globals::patchfilecollector, "$onefile->{'destination'}\n"); }
691
692		my $source = $onefile->{'sourcepath'};
693		my $destination = $onefile->{'destination'};
694		$destination = $subfolderdir . $installer::globals::separator . $destination;
695
696		# Replacing $$ by $ is necessary to install files with $ in its name (back-masquerading)
697		# Otherwise, the following shell command does not work and the file list is not correct
698		$source =~ s/\$\$/\$/;
699		$destination =~ s/\$\$/\$/;
700
701		if ( $^O =~ /cygwin/i )	# Cygwin performance, do not use copy_one_file. "chmod -R" at the end
702		{
703			my $copyreturn = copy($source, $destination);
704
705			if ($copyreturn)
706			{
707				$infoline = "Copy: $source to $destination\n";
708				$returnvalue = 1;
709			}
710			else
711			{
712				$infoline = "ERROR: Could not copy $source to $destination\n";
713				$returnvalue = 0;
714			}
715
716			push(@installer::globals::logfileinfo, $infoline);
717		}
718		else
719		{
720			installer::systemactions::copy_one_file($source, $destination);
721
722			if ( ! $installer::globals::iswindowsbuild )
723			{
724				# see issue 102274
725				my $unixrights = "";
726				if ( $onefile->{'UnixRights'} )
727				{
728					$unixrights = $onefile->{'UnixRights'};
729
730					my $localcall = "$installer::globals::wrapcmd chmod $unixrights \'$destination\' \>\/dev\/null 2\>\&1";
731					system($localcall);
732				}
733			}
734		}
735	}
736
737	# creating Links
738
739	installer::logger::print_message( "... creating links ...\n" );
740	installer::logger::include_header_into_logfile("Creating links:");
741
742	for ( my $i = 0; $i <= $#{$linksref}; $i++ )
743	{
744		my $onelink = ${$linksref}[$i];
745
746		if (( $installer::globals::patch ) && ( $onelink->{'Styles'} ) && ( ! ( $onelink->{'Styles'} =~ /\bPATCH\b/ ))) { next; }
747
748		my $destination = $onelink->{'destination'};
749		$destination = $subfolderdir . $installer::globals::separator . $destination;
750		my $destinationfile = $onelink->{'destinationfile'};
751
752		my $localcall = "ln -sf \'$destinationfile\' \'$destination\' \>\/dev\/null 2\>\&1";
753		system($localcall);
754
755		$infoline = "Creating link: \"ln -sf $destinationfile $destination\"\n";
756		push(@installer::globals::logfileinfo, $infoline);
757	}
758
759	for ( my $i = 0; $i <= $#{$unixlinksref}; $i++ )
760	{
761		my $onelink = ${$unixlinksref}[$i];
762
763		if (( $installer::globals::patch ) && ( $onelink->{'Styles'} ) && ( ! ( $onelink->{'Styles'} =~ /\bPATCH\b/ ))) { next; }
764
765		my $target = $onelink->{'Target'};
766		my $destination = $subfolderdir . $installer::globals::separator . $onelink->{'destination'};
767
768		my $localcall = "ln -sf \'$target\' \'$destination\' \>\/dev\/null 2\>\&1";
769		system($localcall);
770
771		$infoline = "Creating Unix link: \"ln -sf $target $destination\"\n";
772		push(@installer::globals::logfileinfo, $infoline);
773	}
774
775	# Setting privileges for cygwin globally
776
777	if ( $^O =~ /cygwin/i )
778	{
779		installer::logger::print_message( "... changing privileges in $subfolderdir ...\n" );
780		installer::logger::include_header_into_logfile("Changing privileges in $subfolderdir:");
781
782		my $localcall = "chmod -R 755 " . "\"" . $subfolderdir . "\"";
783		system($localcall);
784	}
785
786	installer::logger::print_message( "... removing superfluous directories ...\n" );
787	installer::logger::include_header_into_logfile("Removing superfluous directories:");
788
789	my ( $extensionfolder, $preregdir ) = get_extensions_dir($subfolderdir);
790	installer::systemactions::remove_empty_dirs_in_folder($extensionfolder);
791
792	# Registering the extensions
793
794	installer::logger::print_message( "... registering extensions ...\n" );
795	installer::logger::include_header_into_logfile("Registering extensions:");
796	register_extensions($subfolderdir, $languagestringref, $preregdir);
797
798	if ( $installer::globals::compiler =~ /^unxmacx/ )
799	{
800		installer::worker::put_scpactions_into_installset("$installdir/$packagename");
801	}
802
803	# Creating archive file
804    if ( $installer::globals::packageformat eq "archive" )
805    {
806        create_package($tempinstalldir, $installdir, $packagename, $allvariables, $includepatharrayref, $languagestringref, $installer::globals::archiveformat);
807    }
808    elsif ( $installer::globals::packageformat eq "dmg" )
809    {
810        create_package($installdir, $installdir, $packagename, $allvariables, $includepatharrayref, $languagestringref, ".dmg");
811    }
812
813	# Analyzing the log file
814
815	installer::worker::clean_output_tree();	# removing directories created in the output tree
816	installer::worker::analyze_and_save_logfile($loggingdir, $installdir, $installlogdir, $allsettingsarrayref, $languagestringref, $current_install_number);
817}
818
8191;
820