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::systemactions;
25
26use Cwd;
27use File::Copy;
28use installer::converter;
29use installer::exiter;
30use installer::globals;
31use installer::pathanalyzer;
32use installer::remover;
33
34######################################################
35# Creating a new direcotory
36######################################################
37
38sub create_directory
39{
40	my ($directory) = @_;
41
42	my $returnvalue = 1;
43	my $infoline = "";
44
45	if (!(-d $directory))
46	{
47		$returnvalue = mkdir($directory, 0775);
48
49		if ($returnvalue)
50		{
51			$infoline = "\nCreated directory: $directory\n";
52			push(@installer::globals::logfileinfo, $infoline);
53
54			my $localcall = "chmod 0775 $directory \>\/dev\/null 2\>\&1";
55			system($localcall);
56
57			# chmod 0775 is not sufficient on mac to remove sticky tag
58			$localcall = "chmod a-s $directory \>\/dev\/null 2\>\&1";
59			system($localcall);
60		}
61		else
62		{
63			# New solution in parallel packing: It is possible, that the directory now exists, although it
64			# was not created in this process. There is only an important error, if the directory does not
65			# exist now.
66
67			$infoline = "\nDid not succeed in creating directory: \"$directory\". Further attempts will follow.\n";
68			push(@installer::globals::logfileinfo, $infoline);
69
70			if (!(-d $directory))
71			{
72				# Problem with parallel packaging? -> Try a little harder, before exiting.
73				# Did someone else remove the parent directory in the meantime?
74				my $parentdir = $directory;
75				installer::pathanalyzer::get_path_from_fullqualifiedname(\$parentdir);
76				if (!(-d $parentdir))
77				{
78					$returnvalue = mkdir($parentdir, 0775);
79
80					if ($returnvalue)
81					{
82						$infoline = "\nAttention: Successfully created parent directory (should already be created before): $parentdir\n";
83						push(@installer::globals::logfileinfo, $infoline);
84
85						my $localcall = "chmod 775 $parentdir \>\/dev\/null 2\>\&1";
86						system($localcall);
87					}
88					else
89					{
90						$infoline = "\Error: \"$directory\" could not be created. Even the parent directory \"$parentdir\" does not exist and could not be created.\n";
91						push(@installer::globals::logfileinfo, $infoline);
92						if ( -d $parentdir )
93						{
94							$infoline = "\nAttention: Finally the parent directory \"$parentdir\" exists, but I could not create it.\n";
95							push(@installer::globals::logfileinfo, $infoline);
96						}
97						else
98						{
99							# Now it is time to exit, even the parent could not be created.
100							installer::exiter::exit_program("ERROR: Could not create parent directory \"$parentdir\"", "create_directory");
101						}
102					}
103				}
104
105				# At this point we have to assume, that the parent directory exist.
106				# Trying once more to create the desired directory
107
108				$returnvalue = mkdir($directory, 0775);
109
110				if ($returnvalue)
111				{
112					$infoline = "\nAttention: Created directory \"$directory\" in the second try.\n";
113					push(@installer::globals::logfileinfo, $infoline);
114
115					my $localcall = "chmod 775 $directory \>\/dev\/null 2\>\&1";
116					system($localcall);
117				}
118				else
119				{
120					if ( -d $directory )
121					{
122						$infoline = "\nAttention: Finally the directory \"$directory\" exists, but I could not create it.\n";
123						push(@installer::globals::logfileinfo, $infoline);
124					}
125					else
126					{
127						# It is time to exit, even the second try failed.
128						installer::exiter::exit_program("ERROR: Failed to create the directory: $directory", "create_directory");
129					}
130				}
131			}
132			else
133			{
134				$infoline = "\nAnother process created this directory in exactly this moment :-) : $directory\n";
135				push(@installer::globals::logfileinfo, $infoline);
136			}
137		}
138	}
139	else
140	{
141		$infoline = "\nAlready existing directory, did not create: $directory\n";
142		push(@installer::globals::logfileinfo, $infoline);
143	}
144}
145
146######################################################
147# Creating a new direcotory with defined privileges
148######################################################
149
150sub create_directory_with_privileges
151{
152	my ($directory, $privileges) = @_;
153
154	my $returnvalue = 1;
155	my $infoline = "";
156
157	if (!(-d $directory))
158	{
159		my $localprivileges = oct("0".$privileges); # changes "777" to 0777
160		$returnvalue = mkdir($directory, $localprivileges);
161
162		if ($returnvalue)
163		{
164			$infoline = "\nCreated directory: $directory\n";
165			push(@installer::globals::logfileinfo, $infoline);
166
167			my $localcall = "chmod $privileges $directory \>\/dev\/null 2\>\&1";
168			system($localcall);
169		}
170		else
171		{
172			# New solution in parallel packing: It is possible, that the directory now exists, although it
173			# was not created in this process. There is only an important error, if the directory does not
174			# exist now.
175
176			$infoline = "\nDid not succeed in creating directory: \"$directory\". Further attempts will follow.\n";
177			push(@installer::globals::logfileinfo, $infoline);
178
179			if (!(-d $directory))
180			{
181				# Problem with parallel packaging? -> Try a little harder, before exiting.
182				# Did someone else remove the parent directory in the meantime?
183				my $parentdir = $directory;
184				installer::pathanalyzer::get_path_from_fullqualifiedname(\$parentdir);
185				if (!(-d $parentdir))
186				{
187					$returnvalue = mkdir($directory, $localprivileges);
188
189					if ($returnvalue)
190					{
191						$infoline = "\nAttention: Successfully created parent directory (should already be created before): $parentdir\n";
192						push(@installer::globals::logfileinfo, $infoline);
193
194						my $localcall = "chmod $privileges $parentdir \>\/dev\/null 2\>\&1";
195						system($localcall);
196					}
197					else
198					{
199						$infoline = "\Error: \"$directory\" could not be created. Even the parent directory \"$parentdir\" does not exist and could not be created.\n";
200						push(@installer::globals::logfileinfo, $infoline);
201						if ( -d $parentdir )
202						{
203							$infoline = "\nAttention: Finally the parent directory \"$parentdir\" exists, but I could not create it.\n";
204							push(@installer::globals::logfileinfo, $infoline);
205						}
206						else
207						{
208							# Now it is time to exit, even the parent could not be created.
209							installer::exiter::exit_program("ERROR: Could not create parent directory \"$parentdir\"", "create_directory_with_privileges");
210						}
211					}
212				}
213
214				# At this point we have to assume, that the parent directory exist.
215				# Trying once more to create the desired directory
216
217				$returnvalue = mkdir($directory, $localprivileges);
218
219				if ($returnvalue)
220				{
221					$infoline = "\nAttention: Created directory \"$directory\" in the second try.\n";
222					push(@installer::globals::logfileinfo, $infoline);
223
224					my $localcall = "chmod $privileges $directory \>\/dev\/null 2\>\&1";
225					system($localcall);
226				}
227				else
228				{
229					if ( -d $directory )
230					{
231						$infoline = "\nAttention: Finally the directory \"$directory\" exists, but I could not create it.\n";
232						push(@installer::globals::logfileinfo, $infoline);
233					}
234					else
235					{
236						# It is time to exit, even the second try failed.
237						installer::exiter::exit_program("ERROR: Failed to create the directory: $directory", "create_directory_with_privileges");
238					}
239				}
240			}
241			else
242			{
243				$infoline = "\nAnother process created this directory in exactly this moment :-) : $directory\n";
244				push(@installer::globals::logfileinfo, $infoline);
245			}
246		}
247	}
248	else
249	{
250		$infoline = "\nAlready existing directory, did not create: $directory\n";
251		push(@installer::globals::logfileinfo, $infoline);
252
253		my $localcall = "chmod $privileges $directory \>\/dev\/null 2\>\&1";
254		system($localcall);
255	}
256}
257
258######################################################
259# Removing a new direcotory
260######################################################
261
262sub remove_empty_directory
263{
264	my ($directory) = @_;
265
266	my $returnvalue = 1;
267
268	if (-d $directory)
269	{
270		my $systemcall = "rmdir $directory";
271
272		$returnvalue = system($systemcall);
273
274		my $infoline = "Systemcall: $systemcall\n";
275		push( @installer::globals::logfileinfo, $infoline);
276
277		if ($returnvalue)
278		{
279			$infoline = "ERROR: Could not remove \"$directory\"!\n";
280			push( @installer::globals::logfileinfo, $infoline);
281		}
282		else
283		{
284			$infoline = "Success: Removed \"$directory\"!\n";
285			push( @installer::globals::logfileinfo, $infoline);
286		}
287	}
288}
289
290#######################################################################
291# Calculating the number of languages in the string
292#######################################################################
293
294sub get_number_of_langs
295{
296	my ($languagestring) = @_;
297
298	my $number = 1;
299
300	my $workstring = $languagestring;
301
302	while ( $workstring =~ /^\s*(.*)_(.*?)\s*$/ )
303	{
304		$workstring = $1;
305		$number++;
306	}
307
308	return $number;
309}
310
311#######################################################################
312# Creating the directories, in which files are generated or unzipped
313#######################################################################
314
315sub create_directories
316{
317	my ($newdirectory, $languagesref) =@_;
318
319	$installer::globals::unpackpath =~ s/\Q$installer::globals::separator\E\s*$//;	# removing ending slashes and backslashes
320
321	my $path = "";
322
323	if (( $newdirectory eq "uno" ) || ( $newdirectory eq "zip" ) || ( $newdirectory eq "cab" ) || ( $newdirectory =~ /rdb\s*$/i )) # special handling for zip files, cab files and services file because of performance reasons
324	{
325		if ( $installer::globals::temppathdefined ) { $path = $installer::globals::temppath; }
326		else { $path = $installer::globals::unpackpath; }
327		$path =~ s/\Q$installer::globals::separator\E\s*$//;	# removing ending slashes and backslashes
328		$path = $path . $installer::globals::separator;
329	}
330	elsif ( ( $newdirectory eq "jds" ) )
331	{
332		if ( $installer::globals::jdstemppathdefined ) { $path = $installer::globals::jdstemppath; }
333		else { $path = $installer::globals::unpackpath; }
334		$path =~ s/\Q$installer::globals::separator\E\s*$//;	# removing ending slashes and backslashes
335		$path = $path . $installer::globals::separator;
336		installer::systemactions::create_directory($path);
337	}
338	else
339	{
340		$path = $installer::globals::unpackpath . $installer::globals::separator;
341
342		# special handling, if LOCALINSTALLDIR is set
343		if (( $installer::globals::localinstalldirset ) && ( $newdirectory eq "install" ))
344		{
345			$installer::globals::localinstalldir =~ s/\Q$installer::globals::separator\E\s*$//;
346			$path = $installer::globals::localinstalldir . $installer::globals::separator;
347		}
348	}
349
350	$infoline = "create_directories: Using $path for $newdirectory !\n";
351	push( @installer::globals::logfileinfo, $infoline);
352
353	if ($newdirectory eq "unzip" )	# special handling for common directory
354	{
355		$path = $path  . ".." . $installer::globals::separator . "common" . $installer::globals::productextension . $installer::globals::separator;
356		create_directory($path);
357
358		$path = $path . $newdirectory . $installer::globals::separator;
359		create_directory($path);
360	}
361	else
362	{
363		my $localproductname = $installer::globals::product;
364		my $localproductsubdir = "";
365
366		if ( $installer::globals::product =~ /^\s*(.+?)\_\_(.+?)\s*$/ )
367		{
368			$localproductname = $1;
369			$localproductsubdir = $2;
370		}
371
372		if ( $installer::globals::languagepack ) { $path = $path . $localproductname . "_languagepack" . $installer::globals::separator; }
373		elsif ( $installer::globals::patch ) { $path = $path . $localproductname . "_patch" . $installer::globals::separator; }
374		else { $path = $path . $localproductname . $installer::globals::separator; }
375
376		create_directory($path);
377
378		if ( $localproductsubdir )
379		{
380			$path = $path . $localproductsubdir . $installer::globals::separator;
381			create_directory($path);
382		}
383
384		$path = $path . $installer::globals::installertypedir . $installer::globals::separator;
385		create_directory($path);
386
387		$path = $path . $newdirectory . $installer::globals::separator;
388		create_directory($path);
389
390		my $locallanguagesref = "";
391
392		if ( $$languagesref ) { $locallanguagesref = $$languagesref; }
393
394		if (!($locallanguagesref eq "" ))	# this will be a path like "01_49", for Profiles and ConfigurationFiles, idt-Files
395		{
396			my $languagestring = $$languagesref;
397
398			if (length($languagestring) > $installer::globals::max_lang_length )
399			{
400				my $number_of_languages = get_number_of_langs($languagestring);
401				chomp(my $shorter = `echo $languagestring | md5sum | sed -e "s/ .*//g"`);
402				# $languagestring = $shorter;
403				my $id = substr($shorter, 0, 8); # taking only the first 8 digits
404				$languagestring = "lang_" . $number_of_languages . "_id_" . $id;
405			}
406
407			$path = $path . $languagestring  . $installer::globals::separator;
408			create_directory($path);
409		}
410	}
411
412	installer::remover::remove_ending_pathseparator(\$path);
413
414	$path = installer::converter::make_path_conform($path);
415
416	return $path;
417}
418
419########################
420# Copying one file
421########################
422
423sub copy_one_file
424{
425	my ($source, $dest) = @_;
426
427	my ($returnvalue, $infoline);
428
429	my $copyreturn = copy($source, $dest);
430
431	if ($copyreturn)
432	{
433		$infoline = "Copy: $source to $dest\n";
434		$returnvalue = 1;
435	}
436	else
437	{
438		$infoline = "ERROR: Could not copy $source to $dest\n";
439		$returnvalue = 0;
440	}
441
442	push(@installer::globals::logfileinfo, $infoline);
443
444    if ( !$returnvalue ) {
445        return $returnvalue;
446    }
447
448    # taking care of file attributes
449    if ($installer::globals::iswin && -f $dest) {
450        my $mode = -x $source ? 0775 : 0664;
451        my $mode_str = sprintf("%o", $mode);
452        my $chmodreturn = chmod($mode, $dest);
453    	if ($chmodreturn)
454    	{
455    		$infoline = "chmod $mode_str, $dest\n";
456    		$returnvalue = 1;
457    	}
458    	else
459    	{
460    		$infoline = "WARNING: Could not chmod $dest: $!\n";
461    		$returnvalue = 0;
462    	}
463
464	    push(@installer::globals::logfileinfo, $infoline);
465    }
466
467	return $returnvalue;
468}
469
470##########################
471# Hard linking one file
472##########################
473
474sub hardlink_one_file
475{
476	my ($source, $dest) = @_;
477
478	my ($returnvalue, $infoline);
479
480	my $copyreturn = link($source, $dest);
481
482	if ($copyreturn)
483	{
484		$infoline = "Link: $source to $dest\n";
485		$returnvalue = 1;
486	}
487	else
488	{
489		$infoline = "ERROR: Could not link $source to $dest\n";
490		$returnvalue = 0;
491	}
492
493	push(@installer::globals::logfileinfo, $infoline);
494
495	return $returnvalue;
496}
497
498##########################
499# Soft linking one file
500##########################
501
502sub softlink_one_file
503{
504	my ($source, $dest) = @_;
505
506	my ($returnvalue, $infoline);
507
508	my $linkreturn = symlink($source, $dest);
509
510	if ($linkreturn)
511	{
512		$infoline = "Symlink: $source to $dest\n";
513		$returnvalue = 1;
514	}
515	else
516	{
517		$infoline = "ERROR: Could not symlink $source to $dest\n";
518		$returnvalue = 0;
519	}
520
521	push(@installer::globals::logfileinfo, $infoline);
522
523	return $returnvalue;
524}
525
526########################
527# Renaming one file
528########################
529
530sub rename_one_file
531{
532	my ($source, $dest) = @_;
533
534	my ($returnvalue, $infoline);
535
536	my $renamereturn = rename($source, $dest);
537
538	if ($renamereturn)
539	{
540		$infoline = "Rename: $source to $dest\n";
541		$returnvalue = 1;
542	}
543	else
544	{
545		$infoline = "ERROR: Could not rename $source to $dest\n";
546		$returnvalue = 0;
547	}
548
549	push(@installer::globals::logfileinfo, $infoline);
550
551	return $returnvalue;
552}
553
554##########################################
555# Copying all files from one directory
556# to another directory
557##########################################
558
559sub copy_directory
560{
561	my ($sourcedir, $destdir) = @_;
562
563	my @sourcefiles = ();
564
565	$sourcedir =~ s/\Q$installer::globals::separator\E\s*$//;
566	$destdir =~ s/\Q$installer::globals::separator\E\s*$//;
567
568	my $infoline = "\n";
569	push(@installer::globals::logfileinfo, $infoline);
570	$infoline = "Copying files from directory $sourcedir to directory $destdir\n";
571	push(@installer::globals::logfileinfo, $infoline);
572
573	opendir(DIR, $sourcedir);
574	@sourcefiles = readdir(DIR);
575	closedir(DIR);
576
577	my $onefile;
578
579	foreach $onefile (@sourcefiles)
580	{
581		if ((!($onefile eq ".")) && (!($onefile eq "..")))
582		{
583			my $sourcefile = $sourcedir . $installer::globals::separator . $onefile;
584			my $destfile = $destdir . $installer::globals::separator . $onefile;
585			if ( -f $sourcefile ) 	# only files, no directories
586			{
587				copy_one_file($sourcefile, $destfile);
588			}
589		}
590	}
591}
592
593##########################################
594# Copying all files from one directory
595# to another directory
596##########################################
597
598sub is_empty_dir
599{
600	my ($dir) = @_;
601
602	my $directory_is_empty = 1;
603	my @sourcefiles = ();
604
605	opendir(DIR, $dir);
606	@sourcefiles = readdir(DIR);
607	closedir(DIR);
608
609	my $onefile;
610	my @realcontent = ();
611
612	foreach $onefile (@sourcefiles)
613	{
614		if ((!($onefile eq ".")) && (!($onefile eq "..")))
615		{
616			push(@realcontent, $onefile);
617		}
618	}
619
620	if ( $#realcontent > -1 ) { $directory_is_empty = 0; }
621
622	return $directory_is_empty;
623}
624
625#####################################################################
626# Creating hard links to a complete directory with sub directories.
627#####################################################################
628
629sub hardlink_complete_directory
630{
631	my ($sourcedir, $destdir) = @_;
632
633	my @sourcefiles = ();
634
635	$sourcedir =~ s/\Q$installer::globals::separator\E\s*$//;
636	$destdir =~ s/\Q$installer::globals::separator\E\s*$//;
637
638	if ( ! -d $destdir ) { create_directory($destdir); }
639
640	my $infoline = "\n";
641	push(@installer::globals::logfileinfo, $infoline);
642	$infoline = "Creating hard links for all files from directory $sourcedir to directory $destdir\n";
643	push(@installer::globals::logfileinfo, $infoline);
644
645	opendir(DIR, $sourcedir);
646	@sourcefiles = readdir(DIR);
647	closedir(DIR);
648
649	my $onefile;
650
651	foreach $onefile (@sourcefiles)
652	{
653		if ((!($onefile eq ".")) && (!($onefile eq "..")))
654		{
655			my $source = $sourcedir . $installer::globals::separator . $onefile;
656			my $dest = $destdir . $installer::globals::separator . $onefile;
657			if ( -f $source ) 	# only files, no directories
658			{
659				hardlink_one_file($source, $dest);
660			}
661			if ( -d $source ) 	# recursive
662			{
663				hardlink_complete_directory($source, $dest);
664			}
665		}
666	}
667}
668
669#####################################################################
670# Creating hard links to a complete directory with sub directories.
671#####################################################################
672
673sub softlink_complete_directory
674{
675	my ($sourcedir, $destdir, $depth) = @_;
676
677	my @sourcefiles = ();
678
679	$sourcedir =~ s/\Q$installer::globals::separator\E\s*$//;
680	$destdir =~ s/\Q$installer::globals::separator\E\s*$//;
681
682	if ( ! -d $destdir ) { create_directory($destdir); }
683
684	my $infoline = "\n";
685	push(@installer::globals::logfileinfo, $infoline);
686	$infoline = "Creating soft links for all files from directory $sourcedir to directory $destdir\n";
687	push(@installer::globals::logfileinfo, $infoline);
688
689	opendir(DIR, $sourcedir);
690	@sourcefiles = readdir(DIR);
691	closedir(DIR);
692
693	my $onefile;
694
695	foreach $onefile (@sourcefiles)
696	{
697		if ((!($onefile eq ".")) && (!($onefile eq "..")))
698		{
699			my $source = $sourcedir . $installer::globals::separator . $onefile;
700			my $dest = $destdir . $installer::globals::separator . $onefile;
701			if ( -f $source ) 	# only files, no directories
702			{
703				my $localsource = $source;
704				if ( $depth > 0 ) { for ( my $i = 1; $i <= $depth; $i++ ) { $localsource = "../" . $localsource; } }
705				softlink_one_file($localsource, $dest);
706			}
707			if ( -d $source ) 	# recursive
708			{
709				my $newdepth = $depth + 1;
710				softlink_complete_directory($source, $dest, $newdepth);
711			}
712		}
713	}
714}
715
716#####################################################
717# Copying a complete directory with sub directories.
718#####################################################
719
720sub copy_complete_directory
721{
722	my ($sourcedir, $destdir) = @_;
723
724	my @sourcefiles = ();
725
726	$sourcedir =~ s/\Q$installer::globals::separator\E\s*$//;
727	$destdir =~ s/\Q$installer::globals::separator\E\s*$//;
728
729	if ( ! -d $destdir ) { create_directory($destdir); }
730
731	my $infoline = "\n";
732	push(@installer::globals::logfileinfo, $infoline);
733	$infoline = "Copying files from directory $sourcedir to directory $destdir\n";
734	push(@installer::globals::logfileinfo, $infoline);
735
736	opendir(DIR, $sourcedir);
737	@sourcefiles = readdir(DIR);
738	closedir(DIR);
739
740	my $onefile;
741
742	foreach $onefile (@sourcefiles)
743	{
744		if ((!($onefile eq ".")) && (!($onefile eq "..")))
745		{
746			my $source = $sourcedir . $installer::globals::separator . $onefile;
747			my $dest = $destdir . $installer::globals::separator . $onefile;
748			if ( -f $source ) 	# only files, no directories
749			{
750				copy_one_file($source, $dest);
751			}
752			if ( -d $source ) 	# recursive
753			{
754				if ((!( $source =~ /packages\/SUNW/ )) && (!( $source =~ /packages\/OOO/ )))	# do not copy complete Solaris packages!
755				{
756					copy_complete_directory($source, $dest);
757				}
758			}
759		}
760	}
761}
762
763#####################################################################################
764# Copying a complete directory with sub directories, but not the CVS directories.
765#####################################################################################
766
767sub copy_complete_directory_without_cvs
768{
769	my ($sourcedir, $destdir) = @_;
770
771	my @sourcefiles = ();
772
773	$sourcedir =~ s/\Q$installer::globals::separator\E\s*$//;
774	$destdir =~ s/\Q$installer::globals::separator\E\s*$//;
775
776	if ( ! -d $destdir ) { create_directory($destdir); }
777
778	my $infoline = "\n";
779	push(@installer::globals::logfileinfo, $infoline);
780	$infoline = "Copying files from directory $sourcedir to directory $destdir (without CVS)\n";
781	push(@installer::globals::logfileinfo, $infoline);
782
783	opendir(DIR, $sourcedir);
784	@sourcefiles = readdir(DIR);
785	closedir(DIR);
786
787	my $onefile;
788
789	foreach $onefile (@sourcefiles)
790	{
791		if ((!($onefile eq ".")) && (!($onefile eq "..")) && (!($onefile eq "CVS")))
792		{
793			my $source = $sourcedir . $installer::globals::separator . $onefile;
794			my $dest = $destdir . $installer::globals::separator . $onefile;
795			if ( -f $source ) 	# only files, no directories
796			{
797				copy_one_file($source, $dest);
798			}
799			if ( -d $source ) 	# recursive
800			{
801				copy_complete_directory_without_cvs($source, $dest);
802			}
803		}
804	}
805}
806
807#####################################################
808# Copying all files with a specified file extension
809# from one directory to another directory.
810#####################################################
811
812sub copy_directory_with_fileextension
813{
814	my ($sourcedir, $destdir, $extension) = @_;
815
816	my @sourcefiles = ();
817
818	$sourcedir =~ s/\Q$installer::globals::separator\E\s*$//;
819	$destdir =~ s/\Q$installer::globals::separator\E\s*$//;
820
821	$infoline = "\n";
822	push(@installer::globals::logfileinfo, $infoline);
823	$infoline = "Copying files with extension $extension from directory $sourcedir to directory $destdir\n";
824	push(@installer::globals::logfileinfo, $infoline);
825
826	opendir(DIR, $sourcedir);
827	@sourcefiles = readdir(DIR);
828	closedir(DIR);
829
830	my $onefile;
831
832	foreach $onefile (@sourcefiles)
833	{
834		if ((!($onefile eq ".")) && (!($onefile eq "..")))
835		{
836			if ( $onefile =~ /\.$extension\s*$/ )	# only copying specified files
837			{
838				my $sourcefile = $sourcedir . $installer::globals::separator . $onefile;
839				my $destfile = $destdir . $installer::globals::separator . $onefile;
840				if ( -f $sourcefile ) 	# only files, no directories
841				{
842					copy_one_file($sourcefile, $destfile);
843				}
844			}
845		}
846	}
847}
848
849#########################################################
850# Copying all files without a specified file extension
851# from one directory to another directory.
852#########################################################
853
854sub copy_directory_except_fileextension
855{
856	my ($sourcedir, $destdir, $extension) = @_;
857
858	my @sourcefiles = ();
859
860	$sourcedir =~ s/\Q$installer::globals::separator\E\s*$//;
861	$destdir =~ s/\Q$installer::globals::separator\E\s*$//;
862
863	$infoline = "\n";
864	push(@installer::globals::logfileinfo, $infoline);
865	$infoline = "Copying files without extension $extension from directory $sourcedir to directory $destdir\n";
866	push(@installer::globals::logfileinfo, $infoline);
867
868	opendir(DIR, $sourcedir);
869	@sourcefiles = readdir(DIR);
870	closedir(DIR);
871
872	my $onefile;
873
874	foreach $onefile (@sourcefiles)
875	{
876		if ((!($onefile eq ".")) && (!($onefile eq "..")))
877		{
878			if ( ! ( $onefile =~ /\.$extension\s*$/ ))	# only copying not having the specified extension
879			{
880				my $sourcefile = $sourcedir . $installer::globals::separator . $onefile;
881				my $destfile = $destdir . $installer::globals::separator . $onefile;
882				if ( -f $sourcefile ) 	# only files, no directories
883				{
884					copy_one_file($sourcefile, $destfile);
885				}
886			}
887		}
888	}
889}
890
891########################################################
892# Renaming all files with a specified file extension
893# in a specified directory.
894# Example: "Feature.idt.01" -> "Feature.idt"
895########################################################
896
897sub rename_files_with_fileextension
898{
899	my ($dir, $extension) = @_;
900
901	my @sourcefiles = ();
902
903	$dir =~ s/\Q$installer::globals::separator\E\s*$//;
904
905	my $infoline = "\n";
906	push(@installer::globals::logfileinfo, $infoline);
907	$infoline = "Renaming files with extension \"$extension\" in the directory $dir\n";
908	push(@installer::globals::logfileinfo, $infoline);
909
910	opendir(DIR, $dir);
911	@sourcefiles = readdir(DIR);
912	closedir(DIR);
913
914	my $onefile;
915
916	foreach $onefile (@sourcefiles)
917	{
918		if ((!($onefile eq ".")) && (!($onefile eq "..")))
919		{
920			if ( $onefile =~ /^\s*(\S.*?)\.$extension\s*$/ )	# only renaming specified files
921			{
922				my $destfile = $1;
923				my $sourcefile = $dir . $installer::globals::separator . $onefile;
924				$destfile = $dir . $installer::globals::separator . $destfile;
925				if ( -f $sourcefile ) 	# only files, no directories
926				{
927					rename_one_file($sourcefile, $destfile);
928				}
929			}
930		}
931	}
932}
933
934########################################################
935# Finding all files with a specified file extension
936# in a specified directory.
937########################################################
938
939sub find_file_with_file_extension
940{
941	my ($extension, $dir) = @_;
942
943	my @allfiles = ();
944
945	$dir =~ s/\Q$installer::globals::separator\E\s*$//;
946
947	my $infoline = "\n";
948	push(@installer::globals::logfileinfo, $infoline);
949	$infoline = "Searching files with extension \"$extension\" in the directory $dir\n";
950	push(@installer::globals::logfileinfo, $infoline);
951
952	opendir(DIR, $dir);
953	@sourcefiles = sort readdir(DIR);
954	closedir(DIR);
955
956	my $onefile;
957
958	foreach $onefile (@sourcefiles)
959	{
960		if ((!($onefile eq ".")) && (!($onefile eq "..")))
961		{
962			if ( $onefile =~ /^\s*(\S.*?)\.$extension\s*$/ )
963			{
964				push(@allfiles, $onefile)
965			}
966		}
967	}
968
969	return \@allfiles;
970}
971
972##############################################################
973# Creating a unique directory, for example "01_inprogress_7"
974# in the install directory.
975##############################################################
976
977sub make_numbered_dir
978{
979	my ($newstring, $olddir) = @_;
980
981	my $basedir = $olddir;
982	installer::pathanalyzer::get_path_from_fullqualifiedname(\$basedir);
983
984	my $alldirs = get_all_directories($basedir);
985
986	# searching for the highest number extension
987
988	my $maxnumber = 0;
989
990	for ( my $i = 0; $i <= $#{$alldirs}; $i++ )
991	{
992		if ( ${$alldirs}[$i] =~ /\_(\d+)\s*$/ )
993		{
994			my $number = $1;
995			if ( $number > $maxnumber ) { $maxnumber = $number; }
996		}
997	}
998
999	my $newnumber = $maxnumber + 1;
1000
1001	my $newdir = $olddir . "_" . $newstring . "_" . $newnumber;
1002
1003	my $returndir = "";
1004
1005	if ( move($olddir, $newdir) )
1006	{
1007		$infoline = "\nMoved directory from $olddir to $newdir\n";
1008		push(@installer::globals::logfileinfo, $infoline);
1009		$returndir = $newdir;
1010	}
1011	else
1012	{
1013		$infoline = "\nATTENTION: Could not move directory from $olddir to $newdir, \"make_numbered_dir\"\n";
1014		push(@installer::globals::logfileinfo, $infoline);
1015		$returndir = $olddir;
1016	}
1017
1018	return $returndir;
1019}
1020
1021##############################################################
1022# Determining the highest number in the install directory.
1023##############################################################
1024
1025sub determine_maximum_number
1026{
1027	my ($dir, $languagestringref) = @_;
1028
1029	my $basedir = $dir;
1030	installer::pathanalyzer::get_path_from_fullqualifiedname(\$basedir);
1031
1032	my $alldirs = get_all_directories($basedir);
1033
1034	my $maxnumber = 1;
1035
1036	# In control.pm the installation directory is determined as:
1037	# $installer::globals::build . "_" . $installer::globals::lastminor . "_" .
1038	# "native_inprogress-number_" . $$languagesref . "\." . $installer::globals::buildid;
1039
1040	# searching for the highest number extension after the first "-", which belongs to
1041	# $installer::globals::build, $installer::globals::lastminor and $installer::globals::buildid
1042	# In this step not looking for the language!
1043
1044	my @correctbuildiddirs = ();
1045
1046	for ( my $i = 0; $i <= $#{$alldirs}; $i++ )
1047	{
1048		my $onedir = ${$alldirs}[$i];
1049		installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$onedir);
1050
1051		if ( $onedir =~ /^\s*\Q$installer::globals::build\E\_\Q$installer::globals::lastminor\E\_(.*?)\-(\d+)\_(.*?)\.\Q$installer::globals::buildid\E\s*$/ )
1052		{
1053			my $number = $2;
1054			if ( $number > $maxnumber ) { $maxnumber = $number; }
1055			push(@correctbuildiddirs, $onedir);
1056		}
1057	}
1058
1059	# From all directories with correct $installer::globals::build, $installer::globals::lastminor
1060	# and $installer::globals::buildid, those directories, which already have the maximum number
1061	# have to be selected
1062
1063	my @maximumnumberdirs = ();
1064
1065	for ( my $i = 0; $i <= $#correctbuildiddirs; $i++ )
1066	{
1067		my $onedir = $correctbuildiddirs[$i];
1068
1069		if ( $onedir =~ /^\s*(.*?)\-(\d+)\_(.*?)\.(.*?)\s*$/ )
1070		{
1071			my $number = $2;
1072
1073			if ( $number == $maxnumber )
1074			{
1075				push(@maximumnumberdirs, $onedir);
1076			}
1077		}
1078	}
1079
1080	# @maximumnumberdirs contains only those directories with correct $installer::globals::build,
1081	# $installer::globals::lastminor and $installer::globals::buildid, which already have the maximum number.
1082	# If the current language is part of this directory, the number has to be increased.
1083
1084	my $increase_counter = 0;
1085
1086	for ( my $i = 0; $i <= $#maximumnumberdirs; $i++ )
1087	{
1088		my $onedir = $maximumnumberdirs[$i];
1089
1090		if ( $onedir =~ /^\s*(.*?)\-(\d+)\_(.*?)\.(.*?)\s*$/ )
1091		{
1092			my $number = $2;
1093			my $languagestring = $3;
1094
1095			if ( $languagestring eq $$languagestringref )
1096			{
1097				$increase_counter = 1;
1098			}
1099		}
1100	}
1101
1102	if ( $increase_counter )
1103	{
1104		$maxnumber = $maxnumber + 1;
1105	}
1106
1107	return $maxnumber;
1108}
1109
1110#####################################################################################
1111# Renaming a directory by exchanging a string, for example from "01_inprogress_7"
1112# to "01_witherror_7".
1113#####################################################################################
1114
1115sub rename_string_in_directory
1116{
1117	my ($olddir, $oldstring, $newstring) = @_;
1118
1119	my $newdir = $olddir;
1120	my $infoline = "";
1121
1122	$newdir =~ s/$oldstring/$newstring/g;
1123
1124	if (( -d $newdir ) && ( $olddir ne $newdir )) { remove_complete_directory($newdir, 1); }
1125
1126	if ( move($olddir, $newdir) )
1127	{
1128		$infoline = "\nMoved directory from $olddir to $newdir\n";
1129		push(@installer::globals::logfileinfo, $infoline);
1130	}
1131	else
1132	{
1133		$infoline = "\nATTENTION: Could not move directory from $olddir to $newdir, \"rename_string_in_directory\"\n";
1134		push(@installer::globals::logfileinfo, $infoline);
1135	}
1136
1137	return $newdir;
1138}
1139
1140######################################################
1141# Returning the complete directory name,
1142# input is the first part of the directory name.
1143######################################################
1144
1145sub get_directoryname
1146{
1147	my ($searchdir, $startstring) = @_;
1148
1149	my $dirname = "";
1150	my $founddir = 0;
1151	my $direntry;
1152
1153	opendir(DIR, $searchdir);
1154
1155	foreach $direntry (readdir (DIR))
1156	{
1157		next if $direntry eq ".";
1158		next if $direntry eq "..";
1159
1160		if (( -d $direntry ) && ( $direntry =~ /^\s*\Q$startstring\E/ ))
1161		{
1162			$dirname = $direntry;
1163			$founddir = 1;
1164			last;
1165		}
1166	}
1167
1168	closedir(DIR);
1169
1170	if ( ! $founddir ) { installer::exiter::exit_program("ERROR: Did not find directory beginning with $startstring in directory $searchdir", "get_directoryname"); }
1171
1172	return $dirname;
1173}
1174
1175
1176###################################
1177# Renaming a directory
1178###################################
1179
1180sub rename_directory
1181{
1182	my ($olddir, $newdir) = @_;
1183
1184	my $infoline = "";
1185
1186	if ( move($olddir, $newdir) )
1187	{
1188		$infoline = "\nMoved directory from $olddir to $newdir\n";
1189		push(@installer::globals::logfileinfo, $infoline);
1190	}
1191	else
1192	{
1193		installer::exiter::exit_program("ERROR: Could not move directory from $olddir to $newdir", "rename_directory");
1194		# $infoline = "\nATTENTION: Could not move directory from $olddir to $newdir, \"rename_directory\"\n";
1195		# push(@installer::globals::logfileinfo, $infoline);
1196	}
1197
1198	return $newdir;
1199}
1200
1201##############################################################
1202# Creating a directory next to an existing directory
1203##############################################################
1204
1205sub create_directory_next_to_directory
1206{
1207	my ($topdir, $dirname) = @_;
1208
1209	my $basedir = $topdir;
1210	installer::pathanalyzer::get_path_from_fullqualifiedname(\$basedir);
1211
1212	$basedir =~ s/\Q$installer::globals::separator\E\s*$//;
1213
1214	my $newdir = $basedir . $installer::globals::separator . $dirname;
1215
1216	create_directory($newdir);
1217
1218	return $newdir;
1219}
1220
1221##############################################################
1222# Collecting all directories inside a directory
1223##############################################################
1224
1225sub get_all_directories
1226{
1227	my ($basedir) = @_;
1228
1229	my @alldirs = ();
1230	my $direntry;
1231
1232	$basedir =~ s/\Q$installer::globals::separator\E\s*$//;
1233
1234	opendir(DIR, $basedir);
1235
1236	foreach $direntry (readdir (DIR))
1237	{
1238		next if $direntry eq ".";
1239		next if $direntry eq "..";
1240
1241		my $completeentry = $basedir . $installer::globals::separator . $direntry;
1242
1243		if ( -d $completeentry ) { push(@alldirs, $completeentry); }
1244	}
1245
1246	closedir(DIR);
1247
1248	return \@alldirs;
1249}
1250
1251##############################################################
1252# Collecting all directories inside a directory
1253# Returning without path
1254##############################################################
1255
1256sub get_all_directories_without_path
1257{
1258	my ($basedir) = @_;
1259
1260	my @alldirs = ();
1261	my $direntry;
1262
1263	$basedir =~ s/\Q$installer::globals::separator\E\s*$//;
1264
1265	opendir(DIR, $basedir);
1266
1267	foreach $direntry (readdir (DIR))
1268	{
1269		next if $direntry eq ".";
1270		next if $direntry eq "..";
1271
1272		my $completeentry = $basedir . $installer::globals::separator . $direntry;
1273
1274		if ( -d $completeentry ) { push(@alldirs, $direntry); }
1275	}
1276
1277	closedir(DIR);
1278
1279	return \@alldirs;
1280}
1281
1282##############################################################
1283# Collecting all files inside one directory
1284##############################################################
1285
1286sub get_all_files_from_one_directory
1287{
1288	my ($basedir) = @_;
1289
1290	my @allfiles = ();
1291	my $direntry;
1292
1293	$basedir =~ s/\Q$installer::globals::separator\E\s*$//;
1294
1295	opendir(DIR, $basedir);
1296
1297	foreach $direntry (readdir (DIR))
1298	{
1299		next if $direntry eq ".";
1300		next if $direntry eq "..";
1301
1302		my $completeentry = $basedir . $installer::globals::separator . $direntry;
1303
1304		if ( -f $completeentry ) { push(@allfiles, $completeentry); }
1305	}
1306
1307	closedir(DIR);
1308
1309	return \@allfiles;
1310}
1311
1312##############################################################
1313# Collecting all files inside one directory
1314##############################################################
1315
1316sub get_all_files_from_one_directory_without_path
1317{
1318	my ($basedir) = @_;
1319
1320	my @allfiles = ();
1321	my $direntry;
1322
1323	$basedir =~ s/\Q$installer::globals::separator\E\s*$//;
1324
1325	opendir(DIR, $basedir);
1326
1327	foreach $direntry (readdir (DIR))
1328	{
1329		next if $direntry eq ".";
1330		next if $direntry eq "..";
1331
1332		my $completeentry = $basedir . $installer::globals::separator . $direntry;
1333
1334		if ( -f $completeentry ) { push(@allfiles, $direntry); }
1335	}
1336
1337	closedir(DIR);
1338
1339	return \@allfiles;
1340}
1341
1342##############################################################
1343# Collecting all files and directories inside one directory
1344##############################################################
1345
1346sub read_directory
1347{
1348	my ($basedir) = @_;
1349
1350	my @allcontent = ();
1351	my $direntry;
1352
1353	$basedir =~ s/\Q$installer::globals::separator\E\s*$//;
1354
1355	opendir(DIR, $basedir);
1356
1357	foreach $direntry (readdir (DIR))
1358	{
1359		next if $direntry eq ".";
1360		next if $direntry eq "..";
1361
1362		my $completeentry = $basedir . $installer::globals::separator . $direntry;
1363
1364		if (( -f $completeentry ) || ( -d $completeentry )) { push(@allcontent, $completeentry); }
1365	}
1366
1367	closedir(DIR);
1368
1369	return \@allcontent;
1370}
1371
1372##############################################################
1373# Finding the new content in a directory
1374##############################################################
1375
1376sub find_new_content_in_directory
1377{
1378	my ( $basedir, $oldcontent ) = @_;
1379
1380	my @newcontent = ();
1381	my @allcontent = ();
1382
1383	my $direntry;
1384
1385	$basedir =~ s/\Q$installer::globals::separator\E\s*$//;
1386
1387	opendir(DIR, $basedir);
1388
1389	foreach $direntry (readdir (DIR))
1390	{
1391		next if $direntry eq ".";
1392		next if $direntry eq "..";
1393
1394		my $completeentry = $basedir . $installer::globals::separator . $direntry;
1395
1396		if (( -f $completeentry ) || ( -d $completeentry ))
1397		{
1398			push(@allcontent, $completeentry);
1399			if (! installer::existence::exists_in_array($completeentry, $oldcontent))
1400			{
1401				push(@newcontent, $completeentry);
1402			}
1403		}
1404	}
1405
1406	closedir(DIR);
1407
1408	return (\@newcontent, \@allcontent);
1409}
1410
1411##############################################################
1412# Trying to create a directory, no error if this fails
1413##############################################################
1414
1415sub try_to_create_directory
1416{
1417	my ($directory) = @_;
1418
1419	my $returnvalue = 1;
1420	my $created_directory = 0;
1421
1422	if (!(-d $directory))
1423	{
1424		$returnvalue = mkdir($directory, 0775);
1425
1426		if ($returnvalue)
1427		{
1428			$created_directory = 1;
1429			$infoline = "\nCreated directory: $directory\n";
1430			push(@installer::globals::logfileinfo, $infoline);
1431
1432			my $localcall = "chmod 0775 $directory \>\/dev\/null 2\>\&1";
1433			system($localcall);
1434
1435			# chmod 0775 is not sufficient on mac to remove sticky tag
1436			$localcall = "chmod a-s $directory \>\/dev\/null 2\>\&1";
1437			system($localcall);
1438		}
1439		else
1440		{
1441			$created_directory = 0;
1442		}
1443	}
1444	else
1445	{
1446		$created_directory = 1;
1447	}
1448
1449	return $created_directory;
1450}
1451
1452##############################################################
1453# Creating a complete directory structure
1454##############################################################
1455
1456sub create_directory_structure
1457{
1458	my ($directory) = @_;
1459
1460	if ( ! try_to_create_directory($directory) )
1461	{
1462		my $parentdir = $directory;
1463		installer::pathanalyzer::get_path_from_fullqualifiedname(\$parentdir);
1464
1465		my $infoline = "INFO: Did not create directory $directory\n";
1466		push(@installer::globals::logfileinfo, $infoline);
1467		$infoline = "Now trying to create parent directory $parentdir\n";
1468		push(@installer::globals::logfileinfo, $infoline);
1469
1470		create_directory_structure($parentdir);									# recursive
1471	}
1472
1473	create_directory($directory);	# now it has to succeed
1474}
1475
1476######################################################
1477# Removing a complete directory with subdirectories
1478######################################################
1479
1480sub remove_complete_directory
1481{
1482	my ($directory, $start) = @_;
1483
1484	my @content = ();
1485	my $infoline = "";
1486
1487	$directory =~ s/\Q$installer::globals::separator\E\s*$//;
1488
1489	if ( -d $directory )
1490	{
1491		if ( $start )
1492		{
1493			$infoline = "\n";
1494			push(@installer::globals::logfileinfo, $infoline);
1495			$infoline = "Removing directory $directory\n";
1496			push(@installer::globals::logfileinfo, $infoline);
1497		}
1498
1499		opendir(DIR, $directory);
1500		@content = readdir(DIR);
1501		closedir(DIR);
1502
1503		my $oneitem;
1504
1505		foreach $oneitem (@content)
1506		{
1507			if ((!($oneitem eq ".")) && (!($oneitem eq "..")))
1508			{
1509				my $item = $directory . $installer::globals::separator . $oneitem;
1510
1511				if ( -f $item || -l $item ) 	# deleting files or links
1512				{
1513					unlink($item);
1514				}
1515
1516				if ( -d $item ) 	# recursive
1517				{
1518					remove_complete_directory($item, 0);
1519				}
1520			}
1521		}
1522
1523		# try to remove empty directory
1524
1525		my $returnvalue = rmdir $directory;
1526
1527		if ( ! $returnvalue )
1528		{
1529			$infoline = "Warning: Problem with removing empty dir $directory\n";
1530			push(@installer::globals::logfileinfo, $infoline);
1531		}
1532
1533		# try a little bit harder (sometimes there is a performance problem)
1534		if ( -d $directory )
1535		{
1536			for ( my $j = 1; $j <= 3; $j++ )
1537			{
1538				if ( -d $directory )
1539				{
1540					$infoline = "\n";
1541					push(@installer::globals::logfileinfo, $infoline);
1542					$infoline = "Warning (Try $j): Problems with removing directory $directory\n";
1543					push(@installer::globals::logfileinfo, $infoline);
1544
1545					$returnvalue = rmdir $directory;
1546
1547					if ( $returnvalue )
1548					{
1549						$infoline = "Successfully removed empty dir $directory\n";
1550						push(@installer::globals::logfileinfo, $infoline);
1551					} else {
1552						$infoline = "Warning: rmdir $directory failed.\n";
1553						push(@installer::globals::logfileinfo, $infoline);
1554					}
1555				}
1556			}
1557		}
1558	}
1559}
1560
1561######################################################
1562# Creating a unique directory with number extension
1563######################################################
1564
1565sub create_unique_directory
1566{
1567	my ($directory) = @_;
1568
1569	$directory =~ s/\Q$installer::globals::separator\E\s*$//;
1570	$directory = $directory . "_INCREASINGNUMBER";
1571
1572	my $counter = 1;
1573	my $created = 0;
1574	my $localdirectory = "";
1575
1576	do
1577	{
1578		$localdirectory = $directory;
1579		$localdirectory =~ s/INCREASINGNUMBER/$counter/;
1580		$counter++;
1581
1582		if ( ! -d $localdirectory )
1583		{
1584			create_directory($localdirectory);
1585			$created = 1;
1586		}
1587	}
1588	while ( ! $created );
1589
1590	return $localdirectory;
1591}
1592
1593######################################################
1594# Creating a unique directory with pid extension
1595######################################################
1596
1597sub create_pid_directory
1598{
1599	my ($directory) = @_;
1600
1601	$directory =~ s/\Q$installer::globals::separator\E\s*$//;
1602	my $pid = $$;			# process id
1603	my $time = time();		# time
1604
1605	$directory = $directory . "_" . $pid . $time;
1606
1607	if ( ! -d $directory ) { create_directory($directory); }
1608	else { installer::exiter::exit_program("ERROR: Directory $directory already exists!", "create_pid_directory"); }
1609
1610	return $directory;
1611}
1612
1613##############################################################
1614# Reading all files from a directory and its subdirectories
1615##############################################################
1616
1617sub read_complete_directory
1618{
1619	my ($directory, $pathstring, $filecollector) = @_;
1620
1621	my @content = ();
1622	opendir(DIR, $directory);
1623	@content = readdir(DIR);
1624	closedir(DIR);
1625
1626	my $onefile;
1627
1628	foreach $onefile (@content)
1629	{
1630		if ((!($onefile eq ".")) && (!($onefile eq "..")))
1631		{
1632			my $completefilename = $directory . $installer::globals::separator . $onefile;
1633			my $sep = "";
1634			if ( $pathstring ne "" ) { $sep = $installer::globals::separator; }
1635
1636			if ( ! -d $completefilename ) 	# only files, no directories
1637			{
1638				my $content = $pathstring . $sep . $onefile;
1639				push(@{$filecollector}, $content);
1640			}
1641			else  # recursive for directories
1642			{
1643				my $newpathstring = $pathstring . $sep . $onefile;
1644				read_complete_directory($completefilename, $newpathstring, $filecollector);
1645			}
1646		}
1647	}
1648}
1649
1650##############################################################
1651# Reading all files from a directory and its subdirectories
1652# Version 2
1653##############################################################
1654
1655sub read_full_directory {
1656	my ( $currentdir, $pathstring, $collector ) = @_;
1657	my $item;
1658	my $fullname;
1659	local *DH;
1660
1661	unless (opendir(DH, $currentdir))
1662	{
1663		return;
1664	}
1665	while (defined ($item = readdir(DH)))
1666	{
1667		next if($item eq "." or $item eq "..");
1668		$fullname = $currentdir . $installer::globals::separator . $item;
1669		my $sep = "";
1670		if ( $pathstring ne "" ) { $sep = $installer::globals::separator; }
1671
1672		if( -d $fullname)
1673		{
1674			my $newpathstring = $pathstring . $sep . $item;
1675			read_full_directory($fullname, $newpathstring, $collector) if(-d $fullname);
1676		}
1677		else
1678		{
1679			my $content = $pathstring . $sep . $item;
1680			push(@{$collector}, $content);
1681		}
1682	}
1683	closedir(DH);
1684	return
1685}
1686
1687##############################################################
1688# Removing all empty directories below a specified directory
1689##############################################################
1690
1691sub remove_empty_dirs_in_folder
1692{
1693	my ( $dir ) = @_;
1694
1695	my @content = ();
1696	my $infoline = "";
1697
1698	$dir =~ s/\Q$installer::globals::separator\E\s*$//;
1699
1700	if ( -d $dir )
1701	{
1702		opendir(DIR, $dir);
1703		@content = readdir(DIR);
1704		closedir(DIR);
1705
1706		my $oneitem;
1707
1708		foreach $oneitem (@content)
1709		{
1710			if ((!($oneitem eq ".")) && (!($oneitem eq "..")))
1711			{
1712				my $item = $dir . $installer::globals::separator . $oneitem;
1713
1714				if ( -d $item ) # recursive
1715				{
1716					remove_empty_dirs_in_folder($item);
1717				}
1718			}
1719		}
1720
1721		# try to remove empty directory
1722		my $returnvalue = rmdir $dir;
1723
1724		if ( $returnvalue )
1725		{
1726			$infoline = "Successfully removed empty dir $dir\n";
1727			push(@installer::globals::logfileinfo, $infoline);
1728		}
1729
1730	}
1731
1732}
1733
17341;
1735