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