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