xref: /aoo41x/main/setup_native/scripts/admin.pl (revision 7e90fac2)
1*7e90fac2SAndrew Rist#**************************************************************
2*7e90fac2SAndrew Rist#
3*7e90fac2SAndrew Rist#  Licensed to the Apache Software Foundation (ASF) under one
4*7e90fac2SAndrew Rist#  or more contributor license agreements.  See the NOTICE file
5*7e90fac2SAndrew Rist#  distributed with this work for additional information
6*7e90fac2SAndrew Rist#  regarding copyright ownership.  The ASF licenses this file
7*7e90fac2SAndrew Rist#  to you under the Apache License, Version 2.0 (the
8*7e90fac2SAndrew Rist#  "License"); you may not use this file except in compliance
9*7e90fac2SAndrew Rist#  with the License.  You may obtain a copy of the License at
10*7e90fac2SAndrew Rist#
11*7e90fac2SAndrew Rist#    http://www.apache.org/licenses/LICENSE-2.0
12*7e90fac2SAndrew Rist#
13*7e90fac2SAndrew Rist#  Unless required by applicable law or agreed to in writing,
14*7e90fac2SAndrew Rist#  software distributed under the License is distributed on an
15*7e90fac2SAndrew Rist#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*7e90fac2SAndrew Rist#  KIND, either express or implied.  See the License for the
17*7e90fac2SAndrew Rist#  specific language governing permissions and limitations
18*7e90fac2SAndrew Rist#  under the License.
19*7e90fac2SAndrew Rist#
20*7e90fac2SAndrew Rist#**************************************************************
21*7e90fac2SAndrew Rist
22*7e90fac2SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweiruse Cwd;
25cdf0e10cSrcweiruse File::Copy;
26cdf0e10cSrcweir
27cdf0e10cSrcweir#################################################################################
28cdf0e10cSrcweir# Global settings
29cdf0e10cSrcweir#################################################################################
30cdf0e10cSrcweir
31cdf0e10cSrcweirBEGIN
32cdf0e10cSrcweir{
33cdf0e10cSrcweir	$prog = "msi installer";
34cdf0e10cSrcweir	$targetdir = "";
35cdf0e10cSrcweir	$databasepath = "";
36cdf0e10cSrcweir	$starttime = "";
37cdf0e10cSrcweir	$globaltempdirname = "ooopackaging";
38cdf0e10cSrcweir	$savetemppath = "";
39cdf0e10cSrcweir	$msiinfo_available = 0;
40cdf0e10cSrcweir	$path_displayed = 0;
41cdf0e10cSrcweir	$localmsidbpath = "";
42cdf0e10cSrcweir
43cdf0e10cSrcweir	$plat = $^O;
44cdf0e10cSrcweir
45cdf0e10cSrcweir	if ( $plat =~ /cygwin/i )
46cdf0e10cSrcweir	{
47cdf0e10cSrcweir		$separator = "/";
48cdf0e10cSrcweir		$pathseparator = "\:";
49cdf0e10cSrcweir	}
50cdf0e10cSrcweir	else
51cdf0e10cSrcweir	{
52cdf0e10cSrcweir		$separator = "\\";
53cdf0e10cSrcweir		$pathseparator = "\;";
54cdf0e10cSrcweir	}
55cdf0e10cSrcweir}
56cdf0e10cSrcweir
57cdf0e10cSrcweir#################################################################################
58cdf0e10cSrcweir# Program information
59cdf0e10cSrcweir#################################################################################
60cdf0e10cSrcweir
61cdf0e10cSrcweirsub usage
62cdf0e10cSrcweir{
63cdf0e10cSrcweir	print <<Ende;
64cdf0e10cSrcweir----------------------------------------------------------------------
65cdf0e10cSrcweirThis program installs a Windows Installer installation set
66cdf0e10cSrcweirwithout using msiexec.exe. The installation is comparable
67cdf0e10cSrcweirwith an administrative installation using the Windows Installer
68cdf0e10cSrcweirservice.
69cdf0e10cSrcweirRequired parameter:
70cdf0e10cSrcweir-d Path to installation set or msi database
71cdf0e10cSrcweir-t Target directory
72cdf0e10cSrcweir---------------------------------------------------------------------
73cdf0e10cSrcweirEnde
74cdf0e10cSrcweir	exit(-1);
75cdf0e10cSrcweir}
76cdf0e10cSrcweir
77cdf0e10cSrcweir#################################################################################
78cdf0e10cSrcweir# Collecting parameter
79cdf0e10cSrcweir#################################################################################
80cdf0e10cSrcweir
81cdf0e10cSrcweirsub getparameter
82cdf0e10cSrcweir{
83cdf0e10cSrcweir	if (( $#ARGV < 3 ) || ( $#ARGV > 3 )) { usage(); }
84cdf0e10cSrcweir
85cdf0e10cSrcweir	while ( $#ARGV >= 0 )
86cdf0e10cSrcweir	{
87cdf0e10cSrcweir		my $param = shift(@ARGV);
88cdf0e10cSrcweir
89cdf0e10cSrcweir		if ($param eq "-t") { $targetdir = shift(@ARGV); }
90cdf0e10cSrcweir		elsif ($param eq "-d") { $databasepath = shift(@ARGV); }
91cdf0e10cSrcweir		else
92cdf0e10cSrcweir		{
93cdf0e10cSrcweir			print "\n**********************************************\n";
94cdf0e10cSrcweir			print "Error: Unknows parameter: $param";
95cdf0e10cSrcweir			print "\n**********************************************\n";
96cdf0e10cSrcweir			usage();
97cdf0e10cSrcweir			exit(-1);
98cdf0e10cSrcweir		}
99cdf0e10cSrcweir	}
100cdf0e10cSrcweir}
101cdf0e10cSrcweir
102cdf0e10cSrcweir#################################################################################
103cdf0e10cSrcweir# Checking content of parameter
104cdf0e10cSrcweir#################################################################################
105cdf0e10cSrcweir
106cdf0e10cSrcweirsub controlparameter
107cdf0e10cSrcweir{
108cdf0e10cSrcweir	if ( $targetdir eq "" )
109cdf0e10cSrcweir	{
110cdf0e10cSrcweir		print "\n******************************************************\n";
111cdf0e10cSrcweir		print "Error: Target directory not defined (parameter -t)!";
112cdf0e10cSrcweir		print "\n******************************************************\n";
113cdf0e10cSrcweir		usage();
114cdf0e10cSrcweir		exit(-1);
115cdf0e10cSrcweir	}
116cdf0e10cSrcweir
117cdf0e10cSrcweir	if ( $databasepath eq "" )
118cdf0e10cSrcweir	{
119cdf0e10cSrcweir		print "\n******************************************************\n";
120cdf0e10cSrcweir		print "Error: Path to msi database not defined (parameter -d)!";
121cdf0e10cSrcweir		print "\n******************************************************\n";
122cdf0e10cSrcweir		usage();
123cdf0e10cSrcweir		exit(-1);
124cdf0e10cSrcweir	}
125cdf0e10cSrcweir
126cdf0e10cSrcweir	if ( -d $databasepath )
127cdf0e10cSrcweir	{
128cdf0e10cSrcweir		$databasepath =~ s/\\\s*$//;
129cdf0e10cSrcweir		$databasepath =~ s/\/\s*$//;
130cdf0e10cSrcweir
131cdf0e10cSrcweir		my $msifiles = find_file_with_file_extension("msi", $databasepath);
132cdf0e10cSrcweir
133cdf0e10cSrcweir		if ( $#{$msifiles} < 0 ) { exit_program("ERROR: Did not find msi database in directory $installationdir"); }
134cdf0e10cSrcweir		if ( $#{$msifiles} > 0 ) { exit_program("ERROR: Did find more than one msi database in directory $installationdir"); }
135cdf0e10cSrcweir
136cdf0e10cSrcweir		$databasepath = $databasepath . $separator . ${$msifiles}[0];
137cdf0e10cSrcweir	}
138cdf0e10cSrcweir
139cdf0e10cSrcweir	if ( ! -f $databasepath ) { exit_program("ERROR: Did not find msi database in directory $databasepath."); }
140cdf0e10cSrcweir
141cdf0e10cSrcweir	if ( ! -d $targetdir ) { create_directories($targetdir); }
142cdf0e10cSrcweir}
143cdf0e10cSrcweir
144cdf0e10cSrcweir#############################################################################
145cdf0e10cSrcweir# The program msidb.exe can be located next to the Perl program. Then it is
146cdf0e10cSrcweir# not neccessary to find it in the PATH variable.
147cdf0e10cSrcweir#############################################################################
148cdf0e10cSrcweir
149cdf0e10cSrcweirsub check_local_msidb
150cdf0e10cSrcweir{
151cdf0e10cSrcweir	my $msidbname = "msidb.exe";
152cdf0e10cSrcweir	my $perlprogramm = $0;
153cdf0e10cSrcweir	my $path = $perlprogramm;
154cdf0e10cSrcweir
155cdf0e10cSrcweir	get_path_from_fullqualifiedname(\$path);
156cdf0e10cSrcweir
157cdf0e10cSrcweir	$path =~ s/\\\s*$//;
158cdf0e10cSrcweir	$path =~ s/\/\s*$//;
159cdf0e10cSrcweir
160cdf0e10cSrcweir	my $msidbpath = "";
161cdf0e10cSrcweir	if ( $path =~ /^\s*$/ ) { $msidbpath = $msidbname; }
162cdf0e10cSrcweir	else { $msidbpath = $path . $separator . $msidbname; }
163cdf0e10cSrcweir
164cdf0e10cSrcweir	if ( -f $msidbpath )
165cdf0e10cSrcweir	{
166cdf0e10cSrcweir		$localmsidbpath = $msidbpath;
167cdf0e10cSrcweir		print "Using $msidbpath (next to \"admin.pl\")\n";
168cdf0e10cSrcweir	}
169cdf0e10cSrcweir}
170cdf0e10cSrcweir
171cdf0e10cSrcweir#############################################################################
172cdf0e10cSrcweir# Converting a string list with separator $listseparator
173cdf0e10cSrcweir# into an array
174cdf0e10cSrcweir#############################################################################
175cdf0e10cSrcweir
176cdf0e10cSrcweirsub convert_stringlist_into_array
177cdf0e10cSrcweir{
178cdf0e10cSrcweir	my ( $includestringref, $listseparator ) = @_;
179cdf0e10cSrcweir
180cdf0e10cSrcweir	my @newarray = ();
181cdf0e10cSrcweir	my $first;
182cdf0e10cSrcweir	my $last = ${$includestringref};
183cdf0e10cSrcweir
184cdf0e10cSrcweir	while ( $last =~ /^\s*(.+?)\Q$listseparator\E(.+)\s*$/)	# "$" for minimal matching
185cdf0e10cSrcweir	{
186cdf0e10cSrcweir		$first = $1;
187cdf0e10cSrcweir		$last = $2;
188cdf0e10cSrcweir		# Problem with two directly following listseparators. For example a path with two ";;" directly behind each other
189cdf0e10cSrcweir		$first =~ s/^$listseparator//;
190cdf0e10cSrcweir		push(@newarray, "$first\n");
191cdf0e10cSrcweir	}
192cdf0e10cSrcweir
193cdf0e10cSrcweir	push(@newarray, "$last\n");
194cdf0e10cSrcweir
195cdf0e10cSrcweir	return \@newarray;
196cdf0e10cSrcweir}
197cdf0e10cSrcweir
198cdf0e10cSrcweir#########################################################
199cdf0e10cSrcweir# Checking the local system
200cdf0e10cSrcweir# Checking existence of needed files in include path
201cdf0e10cSrcweir#########################################################
202cdf0e10cSrcweir
203cdf0e10cSrcweirsub check_system_path
204cdf0e10cSrcweir{
205cdf0e10cSrcweir	my $onefile;
206cdf0e10cSrcweir	my $error = 0;
207cdf0e10cSrcweir	my $pathvariable = $ENV{'PATH'};
208cdf0e10cSrcweir	my $local_pathseparator = $pathseparator;
209cdf0e10cSrcweir
210cdf0e10cSrcweir	if( $^O =~ /cygwin/i )
211cdf0e10cSrcweir	{	# When using cygwin's perl the PATH variable is POSIX style and ...
212cdf0e10cSrcweir		$pathvariable = qx{cygpath -mp "$pathvariable"} ;
213cdf0e10cSrcweir		# has to be converted to DOS style for further use.
214cdf0e10cSrcweir		$local_pathseparator = ';';
215cdf0e10cSrcweir	}
216cdf0e10cSrcweir	my $patharrayref = convert_stringlist_into_array(\$pathvariable, $local_pathseparator);
217cdf0e10cSrcweir
218cdf0e10cSrcweir	my @needed_files_in_path = ("expand.exe");
219cdf0e10cSrcweir	if ( $localmsidbpath eq "" ) { push(@needed_files_in_path, "msidb.exe"); } # not found locally -> search in path
220cdf0e10cSrcweir	my @optional_files_in_path = ("msiinfo.exe");
221cdf0e10cSrcweir
222cdf0e10cSrcweir	print("\nChecking required files:\n");
223cdf0e10cSrcweir
224cdf0e10cSrcweir	foreach $onefile ( @needed_files_in_path )
225cdf0e10cSrcweir	{
226cdf0e10cSrcweir		print("...... searching $onefile ...");
227cdf0e10cSrcweir
228cdf0e10cSrcweir		my $fileref = get_sourcepath_from_filename_and_includepath(\$onefile, $patharrayref);
229cdf0e10cSrcweir
230cdf0e10cSrcweir		if ( $$fileref eq "" )
231cdf0e10cSrcweir		{
232cdf0e10cSrcweir			$error = 1;
233cdf0e10cSrcweir			print( "$onefile not found\n" );
234cdf0e10cSrcweir		}
235cdf0e10cSrcweir		else
236cdf0e10cSrcweir		{
237cdf0e10cSrcweir			print( "\tFound: $$fileref\n" );
238cdf0e10cSrcweir		}
239cdf0e10cSrcweir	}
240cdf0e10cSrcweir
241cdf0e10cSrcweir	if ( $error ) { exit_program("ERROR: Could not find all needed files in path (using setsolar should help)!"); }
242cdf0e10cSrcweir
243cdf0e10cSrcweir	print("\nChecking optional files:\n");
244cdf0e10cSrcweir
245cdf0e10cSrcweir	foreach $onefile ( @optional_files_in_path )
246cdf0e10cSrcweir	{
247cdf0e10cSrcweir		print("...... searching $onefile ...");
248cdf0e10cSrcweir
249cdf0e10cSrcweir		my $fileref = get_sourcepath_from_filename_and_includepath(\$onefile, $patharrayref);
250cdf0e10cSrcweir
251cdf0e10cSrcweir		if ( $$fileref eq "" )
252cdf0e10cSrcweir		{
253cdf0e10cSrcweir			print( "$onefile not found\n" );
254cdf0e10cSrcweir			if ( $onefile eq "msiinfo.exe" ) { $msiinfo_available = 0; }
255cdf0e10cSrcweir		}
256cdf0e10cSrcweir		else
257cdf0e10cSrcweir		{
258cdf0e10cSrcweir			print( "\tFound: $$fileref\n" );
259cdf0e10cSrcweir			if ( $onefile eq "msiinfo.exe" ) { $msiinfo_available = 1; }
260cdf0e10cSrcweir		}
261cdf0e10cSrcweir	}
262cdf0e10cSrcweir
263cdf0e10cSrcweir}
264cdf0e10cSrcweir
265cdf0e10cSrcweir##########################################################################
266cdf0e10cSrcweir# Searching a file in a list of pathes
267cdf0e10cSrcweir##########################################################################
268cdf0e10cSrcweir
269cdf0e10cSrcweirsub get_sourcepath_from_filename_and_includepath
270cdf0e10cSrcweir{
271cdf0e10cSrcweir	my ($searchfilenameref, $includepatharrayref) = @_;
272cdf0e10cSrcweir
273cdf0e10cSrcweir	my $onefile = "";
274cdf0e10cSrcweir	my $foundsourcefile = 0;
275cdf0e10cSrcweir
276cdf0e10cSrcweir	for ( my $j = 0; $j <= $#{$includepatharrayref}; $j++ )
277cdf0e10cSrcweir	{
278cdf0e10cSrcweir		my $includepath = ${$includepatharrayref}[$j];
279cdf0e10cSrcweir		$includepath =~ s/^\s*//;
280cdf0e10cSrcweir		$includepath =~ s/\s*$//;
281cdf0e10cSrcweir
282cdf0e10cSrcweir		$onefile = $includepath . $separator . $$searchfilenameref;
283cdf0e10cSrcweir
284cdf0e10cSrcweir		if ( -f $onefile )
285cdf0e10cSrcweir		{
286cdf0e10cSrcweir			$foundsourcefile = 1;
287cdf0e10cSrcweir			last;
288cdf0e10cSrcweir		}
289cdf0e10cSrcweir	}
290cdf0e10cSrcweir
291cdf0e10cSrcweir	if (!($foundsourcefile)) { $onefile = ""; }
292cdf0e10cSrcweir
293cdf0e10cSrcweir	return \$onefile;
294cdf0e10cSrcweir}
295cdf0e10cSrcweir
296cdf0e10cSrcweir##############################################################
297cdf0e10cSrcweir# Removing all empty directories below a specified directory
298cdf0e10cSrcweir##############################################################
299cdf0e10cSrcweir
300cdf0e10cSrcweirsub remove_empty_dirs_in_folder
301cdf0e10cSrcweir{
302cdf0e10cSrcweir	my ( $dir, $firstrun ) = @_;
303cdf0e10cSrcweir
304cdf0e10cSrcweir	if ( $firstrun )
305cdf0e10cSrcweir	{
306cdf0e10cSrcweir		print "Removing superfluous directories\n";
307cdf0e10cSrcweir	}
308cdf0e10cSrcweir
309cdf0e10cSrcweir	my @content = ();
310cdf0e10cSrcweir
311cdf0e10cSrcweir	$dir =~ s/\Q$separator\E\s*$//;
312cdf0e10cSrcweir
313cdf0e10cSrcweir	if ( -d $dir )
314cdf0e10cSrcweir	{
315cdf0e10cSrcweir		opendir(DIR, $dir);
316cdf0e10cSrcweir		@content = readdir(DIR);
317cdf0e10cSrcweir		closedir(DIR);
318cdf0e10cSrcweir
319cdf0e10cSrcweir		my $oneitem;
320cdf0e10cSrcweir
321cdf0e10cSrcweir		foreach $oneitem (@content)
322cdf0e10cSrcweir		{
323cdf0e10cSrcweir			if ((!($oneitem eq ".")) && (!($oneitem eq "..")))
324cdf0e10cSrcweir			{
325cdf0e10cSrcweir				my $item = $dir . $separator . $oneitem;
326cdf0e10cSrcweir
327cdf0e10cSrcweir				if ( -d $item ) # recursive
328cdf0e10cSrcweir				{
329cdf0e10cSrcweir					remove_empty_dirs_in_folder($item, 0);
330cdf0e10cSrcweir				}
331cdf0e10cSrcweir			}
332cdf0e10cSrcweir		}
333cdf0e10cSrcweir
334cdf0e10cSrcweir		# try to remove empty directory
335cdf0e10cSrcweir		my $returnvalue = rmdir $dir;
336cdf0e10cSrcweir
337cdf0e10cSrcweir		# if ( $returnvalue ) { print "Successfully removed empty dir $dir\n"; }
338cdf0e10cSrcweir	}
339cdf0e10cSrcweir}
340cdf0e10cSrcweir
341cdf0e10cSrcweir####################################################
342cdf0e10cSrcweir# Detecting the directory with extensions
343cdf0e10cSrcweir####################################################
344cdf0e10cSrcweir
345cdf0e10cSrcweirsub get_extensions_dir
346cdf0e10cSrcweir{
347cdf0e10cSrcweir	my ( $unopkgfile ) = @_;
348cdf0e10cSrcweir
349cdf0e10cSrcweir	my $localbranddir = $unopkgfile;
350cdf0e10cSrcweir	get_path_from_fullqualifiedname(\$localbranddir); # "program" dir in brand layer
351cdf0e10cSrcweir	get_path_from_fullqualifiedname(\$localbranddir); # root dir in brand layer
352cdf0e10cSrcweir	$localbranddir =~ s/\Q$separator\E\s*$//;
353cdf0e10cSrcweir	my $extensiondir = $localbranddir . $separator . "share" . $separator . "extensions";
354cdf0e10cSrcweir	my $preregdir = $localbranddir . $separator . "share" . $separator . "prereg" . $separator . "bundled";
355cdf0e10cSrcweir
356cdf0e10cSrcweir	return ($extensiondir, $preregdir);
357cdf0e10cSrcweir}
358cdf0e10cSrcweir
359cdf0e10cSrcweir########################################################
360cdf0e10cSrcweir# Finding all files with a specified file extension
361cdf0e10cSrcweir# in a specified directory.
362cdf0e10cSrcweir########################################################
363cdf0e10cSrcweir
364cdf0e10cSrcweirsub find_file_with_file_extension
365cdf0e10cSrcweir{
366cdf0e10cSrcweir	my ($extension, $dir) = @_;
367cdf0e10cSrcweir
368cdf0e10cSrcweir	my @allfiles = ();
369cdf0e10cSrcweir	my @sourcefiles = ();
370cdf0e10cSrcweir
371cdf0e10cSrcweir	$dir =~ s/\Q$separator\E\s*$//;
372cdf0e10cSrcweir
373cdf0e10cSrcweir	opendir(DIR, $dir);
374cdf0e10cSrcweir	@sourcefiles = readdir(DIR);
375cdf0e10cSrcweir	closedir(DIR);
376cdf0e10cSrcweir
377cdf0e10cSrcweir	my $onefile;
378cdf0e10cSrcweir
379cdf0e10cSrcweir	foreach $onefile (@sourcefiles)
380cdf0e10cSrcweir	{
381cdf0e10cSrcweir		if ((!($onefile eq ".")) && (!($onefile eq "..")))
382cdf0e10cSrcweir		{
383cdf0e10cSrcweir			if ( $onefile =~ /^\s*(\S.*?)\.$extension\s*$/ )
384cdf0e10cSrcweir			{
385cdf0e10cSrcweir				push(@allfiles, $onefile)
386cdf0e10cSrcweir			}
387cdf0e10cSrcweir		}
388cdf0e10cSrcweir	}
389cdf0e10cSrcweir
390cdf0e10cSrcweir	return \@allfiles;
391cdf0e10cSrcweir}
392cdf0e10cSrcweir
393cdf0e10cSrcweir##############################################################
394cdf0e10cSrcweir# Creating a directory with all parent directories
395cdf0e10cSrcweir##############################################################
396cdf0e10cSrcweir
397cdf0e10cSrcweirsub create_directories
398cdf0e10cSrcweir{
399cdf0e10cSrcweir	my ($directory) = @_;
400cdf0e10cSrcweir
401cdf0e10cSrcweir	if ( ! try_to_create_directory($directory) )
402cdf0e10cSrcweir	{
403cdf0e10cSrcweir		my $parentdir = $directory;
404cdf0e10cSrcweir		get_path_from_fullqualifiedname(\$parentdir);
405cdf0e10cSrcweir		create_directories($parentdir);   # recursive
406cdf0e10cSrcweir	}
407cdf0e10cSrcweir
408cdf0e10cSrcweir	create_directory($directory);	# now it has to succeed
409cdf0e10cSrcweir}
410cdf0e10cSrcweir
411cdf0e10cSrcweir##############################################################
412cdf0e10cSrcweir# Creating one directory
413cdf0e10cSrcweir##############################################################
414cdf0e10cSrcweir
415cdf0e10cSrcweirsub create_directory
416cdf0e10cSrcweir{
417cdf0e10cSrcweir	my ($directory) = @_;
418cdf0e10cSrcweir
419cdf0e10cSrcweir	if ( ! -d $directory ) { mkdir($directory, 0775); }
420cdf0e10cSrcweir}
421cdf0e10cSrcweir
422cdf0e10cSrcweir##############################################################
423cdf0e10cSrcweir# Trying to create a directory, no error if this fails
424cdf0e10cSrcweir##############################################################
425cdf0e10cSrcweir
426cdf0e10cSrcweirsub try_to_create_directory
427cdf0e10cSrcweir{
428cdf0e10cSrcweir	my ($directory) = @_;
429cdf0e10cSrcweir
430cdf0e10cSrcweir	my $returnvalue = 1;
431cdf0e10cSrcweir	my $created_directory = 0;
432cdf0e10cSrcweir
433cdf0e10cSrcweir	if (!(-d $directory))
434cdf0e10cSrcweir	{
435cdf0e10cSrcweir		$returnvalue = mkdir($directory, 0775);
436cdf0e10cSrcweir
437cdf0e10cSrcweir		if ($returnvalue)
438cdf0e10cSrcweir		{
439cdf0e10cSrcweir			$created_directory = 1;
440cdf0e10cSrcweir
441cdf0e10cSrcweir            my $localcall = "chmod 775 $directory \>\/dev\/null 2\>\&1";
442cdf0e10cSrcweir            system($localcall);
443cdf0e10cSrcweir		}
444cdf0e10cSrcweir		else
445cdf0e10cSrcweir		{
446cdf0e10cSrcweir			$created_directory = 0;
447cdf0e10cSrcweir		}
448cdf0e10cSrcweir	}
449cdf0e10cSrcweir	else
450cdf0e10cSrcweir	{
451cdf0e10cSrcweir		$created_directory = 1;
452cdf0e10cSrcweir	}
453cdf0e10cSrcweir
454cdf0e10cSrcweir	return $created_directory;
455cdf0e10cSrcweir}
456cdf0e10cSrcweir
457cdf0e10cSrcweir###########################################
458cdf0e10cSrcweir# Getting path from full file name
459cdf0e10cSrcweir###########################################
460cdf0e10cSrcweir
461cdf0e10cSrcweirsub get_path_from_fullqualifiedname
462cdf0e10cSrcweir{
463cdf0e10cSrcweir	my ($longfilenameref) = @_;
464cdf0e10cSrcweir
465cdf0e10cSrcweir	if ( $$longfilenameref =~ /\Q$separator\E/ )	# Is there a separator in the path? Otherwise the path is empty.
466cdf0e10cSrcweir	{
467cdf0e10cSrcweir		if ( $$longfilenameref =~ /^\s*(\S.*\Q$separator\E)(\S.+\S?)/ )
468cdf0e10cSrcweir		{
469cdf0e10cSrcweir			$$longfilenameref = $1;
470cdf0e10cSrcweir		}
471cdf0e10cSrcweir	}
472cdf0e10cSrcweir	else
473cdf0e10cSrcweir	{
474cdf0e10cSrcweir		$$longfilenameref = "";	# there is no path
475cdf0e10cSrcweir	}
476cdf0e10cSrcweir}
477cdf0e10cSrcweir
478cdf0e10cSrcweir##############################################################
479cdf0e10cSrcweir# Getting file name from full file name
480cdf0e10cSrcweir##############################################################
481cdf0e10cSrcweir
482cdf0e10cSrcweirsub make_absolute_filename_to_relative_filename
483cdf0e10cSrcweir{
484cdf0e10cSrcweir	my ($longfilenameref) = @_;
485cdf0e10cSrcweir
486cdf0e10cSrcweir	# Either '/' or '\'.
487cdf0e10cSrcweir	if ( $$longfilenameref =~ /^.*[\/\\](\S.+\S?)/ )
488cdf0e10cSrcweir	{
489cdf0e10cSrcweir		$$longfilenameref = $1;
490cdf0e10cSrcweir	}
491cdf0e10cSrcweir}
492cdf0e10cSrcweir
493cdf0e10cSrcweir############################################
494cdf0e10cSrcweir# Exiting the program with an error
495cdf0e10cSrcweir# This function is used instead of "die"
496cdf0e10cSrcweir############################################
497cdf0e10cSrcweir
498cdf0e10cSrcweirsub exit_program
499cdf0e10cSrcweir{
500cdf0e10cSrcweir	my ($message) = @_;
501cdf0e10cSrcweir
502cdf0e10cSrcweir	print "\n***************************************************************\n";
503cdf0e10cSrcweir	print "$message\n";
504cdf0e10cSrcweir	print "***************************************************************\n";
505cdf0e10cSrcweir	remove_complete_directory($savetemppath, 1);
506cdf0e10cSrcweir	print "\n" . get_time_string();
507cdf0e10cSrcweir	exit(-1);
508cdf0e10cSrcweir}
509cdf0e10cSrcweir
510cdf0e10cSrcweir#################################################################################
511cdf0e10cSrcweir# Unpacking cabinet files with expand
512cdf0e10cSrcweir#################################################################################
513cdf0e10cSrcweir
514cdf0e10cSrcweirsub unpack_cabinet_file
515cdf0e10cSrcweir{
516cdf0e10cSrcweir	my ($cabfilename, $unpackdir) = @_;
517cdf0e10cSrcweir
518cdf0e10cSrcweir	my $expandfile = "expand.exe"; # has to be in the PATH
519cdf0e10cSrcweir
520cdf0e10cSrcweir	# expand.exe has to be located in the system directory.
521cdf0e10cSrcweir	# Cygwin has another tool expand.exe, that converts tabs to spaces. This cannot be used of course.
522cdf0e10cSrcweir	# But this wrong expand.exe is typically in the PATH before this expand.exe, to unpack
523cdf0e10cSrcweir	# cabinet files.
524cdf0e10cSrcweir
525cdf0e10cSrcweir	if ( $^O =~ /cygwin/i )
526cdf0e10cSrcweir	{
527cdf0e10cSrcweir		$expandfile = $ENV{'SYSTEMROOT'} . "/system32/expand.exe"; # Has to be located in the systemdirectory
528cdf0e10cSrcweir		$expandfile =~ s/\\/\//;
529cdf0e10cSrcweir		if ( ! -f $expandfile ) { exit_program("ERROR: Did not find file $expandfile in the Windows system folder!"); }
530cdf0e10cSrcweir	}
531cdf0e10cSrcweir
532cdf0e10cSrcweir	my $expandlogfile = $unpackdir . $separator . "expand.log";
533cdf0e10cSrcweir
534cdf0e10cSrcweir	# exclude cabinet file
535cdf0e10cSrcweir	# my $systemcall = $cabarc . " -o X " . $mergemodulehash->{'cabinetfile'};
536cdf0e10cSrcweir
537cdf0e10cSrcweir	my $systemcall = "";
538cdf0e10cSrcweir	if ( $^O =~ /cygwin/i ) {
539cdf0e10cSrcweir		my $localunpackdir = qx{cygpath -w "$unpackdir"};
540cdf0e10cSrcweir		$localunpackdir =~ s/\\/\\\\/g;
541cdf0e10cSrcweir
542cdf0e10cSrcweir		my $localcabfilename = qx{cygpath -w "$cabfilename"};
543cdf0e10cSrcweir		$localcabfilename =~ s/\\/\\\\/g;
544cdf0e10cSrcweir		$localcabfilename =~ s/\s*$//g;
545cdf0e10cSrcweir
546cdf0e10cSrcweir		$systemcall = $expandfile . " " . $localcabfilename . " -F:\* " . $localunpackdir . " \>\/dev\/null 2\>\&1";
547cdf0e10cSrcweir	}
548cdf0e10cSrcweir	else
549cdf0e10cSrcweir	{
550cdf0e10cSrcweir		$systemcall = $expandfile . " " . $cabfilename . " -F:\* " . $unpackdir . " \> " . $expandlogfile;
551cdf0e10cSrcweir	}
552cdf0e10cSrcweir
553cdf0e10cSrcweir	my $returnvalue = system($systemcall);
554cdf0e10cSrcweir
555cdf0e10cSrcweir	if ($returnvalue) { exit_program("ERROR: Could not execute $systemcall !"); }
556cdf0e10cSrcweir}
557cdf0e10cSrcweir
558cdf0e10cSrcweir#################################################################################
559cdf0e10cSrcweir# Extracting tables from msi database
560cdf0e10cSrcweir#################################################################################
561cdf0e10cSrcweir
562cdf0e10cSrcweirsub extract_tables_from_database
563cdf0e10cSrcweir{
564cdf0e10cSrcweir	my ($fullmsidatabasepath, $workdir, $tablelist) = @_;
565cdf0e10cSrcweir
566cdf0e10cSrcweir	my $msidb = "msidb.exe";	# Has to be in the path
567cdf0e10cSrcweir	if ( $localmsidbpath ) { $msidb = $localmsidbpath; }
568cdf0e10cSrcweir	my $infoline = "";
569cdf0e10cSrcweir	my $systemcall = "";
570cdf0e10cSrcweir	my $returnvalue = "";
571cdf0e10cSrcweir
572cdf0e10cSrcweir	if ( $^O =~ /cygwin/i ) {
573cdf0e10cSrcweir		chomp( $fullmsidatabasepath = qx{cygpath -w "$fullmsidatabasepath"} );
574cdf0e10cSrcweir		# msidb.exe really wants backslashes. (And double escaping because system() expands the string.)
575cdf0e10cSrcweir		$fullmsidatabasepath =~ s/\\/\\\\/g;
576cdf0e10cSrcweir		$workdir =~ s/\\/\\\\/g;
577cdf0e10cSrcweir		# and if there are still slashes, they also need to be double backslash
578cdf0e10cSrcweir		$fullmsidatabasepath =~ s/\//\\\\/g;
579cdf0e10cSrcweir		$workdir =~ s/\//\\\\/g;
580cdf0e10cSrcweir	}
581cdf0e10cSrcweir
582cdf0e10cSrcweir	# Export of all tables by using "*"
583cdf0e10cSrcweir
584cdf0e10cSrcweir	$systemcall = $msidb . " -d " . $fullmsidatabasepath . " -f " . $workdir . " -e $tablelist";
585cdf0e10cSrcweir	print "\nAnalyzing msi database\n";
586cdf0e10cSrcweir	$returnvalue = system($systemcall);
587cdf0e10cSrcweir
588cdf0e10cSrcweir	if ($returnvalue)
589cdf0e10cSrcweir	{
590cdf0e10cSrcweir		$infoline = "ERROR: Could not execute $systemcall !\n";
591cdf0e10cSrcweir		exit_program($infoline);
592cdf0e10cSrcweir	}
593cdf0e10cSrcweir}
594cdf0e10cSrcweir
595cdf0e10cSrcweir########################################################
596cdf0e10cSrcweir# Check, if this installation set contains
597cdf0e10cSrcweir# internal cabinet files included into the msi
598cdf0e10cSrcweir# database.
599cdf0e10cSrcweir########################################################
600cdf0e10cSrcweir
601cdf0e10cSrcweirsub check_for_internal_cabfiles
602cdf0e10cSrcweir{
603cdf0e10cSrcweir	my ($cabfilehash) = @_;
604cdf0e10cSrcweir
605cdf0e10cSrcweir	my $contains_internal_cabfiles = 0;
606cdf0e10cSrcweir	my %allcabfileshash = ();
607cdf0e10cSrcweir
608cdf0e10cSrcweir	foreach my $filename ( keys %{$cabfilehash} )
609cdf0e10cSrcweir	{
610cdf0e10cSrcweir		if ( $filename =~ /^\s*\#/ )	 # starting with a hash
611cdf0e10cSrcweir		{
612cdf0e10cSrcweir			$contains_internal_cabfiles = 1;
613cdf0e10cSrcweir			# setting real filename without hash as key and name with hash as value
614cdf0e10cSrcweir			my $realfilename = $filename;
615cdf0e10cSrcweir			$realfilename =~ s/^\s*\#//;
616cdf0e10cSrcweir			$allcabfileshash{$realfilename} = $filename;
617cdf0e10cSrcweir		}
618cdf0e10cSrcweir	}
619cdf0e10cSrcweir
620cdf0e10cSrcweir	return ( $contains_internal_cabfiles, \%allcabfileshash );
621cdf0e10cSrcweir}
622cdf0e10cSrcweir
623cdf0e10cSrcweir#################################################################
624cdf0e10cSrcweir# Exclude all cab files from the msi database.
625cdf0e10cSrcweir#################################################################
626cdf0e10cSrcweir
627cdf0e10cSrcweirsub extract_cabs_from_database
628cdf0e10cSrcweir{
629cdf0e10cSrcweir	my ($msidatabase, $allcabfiles) = @_;
630cdf0e10cSrcweir
631cdf0e10cSrcweir	my $infoline = "";
632cdf0e10cSrcweir	my $fullsuccess = 1;
633cdf0e10cSrcweir	my $msidb = "msidb.exe";	# Has to be in the path
634cdf0e10cSrcweir	if ( $localmsidbpath ) { $msidb = $localmsidbpath; }
635cdf0e10cSrcweir
636cdf0e10cSrcweir	my @all_excluded_cabfiles = ();
637cdf0e10cSrcweir
638cdf0e10cSrcweir	if( $^O =~ /cygwin/i )
639cdf0e10cSrcweir	{
640cdf0e10cSrcweir		$msidatabase = qx{cygpath -w "$msidatabase"};
641cdf0e10cSrcweir		$msidatabase =~ s/\\/\\\\/g;
642cdf0e10cSrcweir		$msidatabase =~ s/\s*$//g;
643cdf0e10cSrcweir	}
644cdf0e10cSrcweir	else
645cdf0e10cSrcweir	{
646cdf0e10cSrcweir		# msidb.exe really wants backslashes. (And double escaping because system() expands the string.)
647cdf0e10cSrcweir		$msidatabase =~ s/\//\\\\/g;
648cdf0e10cSrcweir	}
649cdf0e10cSrcweir
650cdf0e10cSrcweir	foreach my $onefile ( keys %{$allcabfiles} )
651cdf0e10cSrcweir	{
652cdf0e10cSrcweir		my $systemcall = $msidb . " -d " . $msidatabase . " -x " . $onefile;
653cdf0e10cSrcweir 		system($systemcall);
654cdf0e10cSrcweir 		push(@all_excluded_cabfiles, $onefile);
655cdf0e10cSrcweir	}
656cdf0e10cSrcweir
657cdf0e10cSrcweir	\@all_excluded_cabfiles;
658cdf0e10cSrcweir}
659cdf0e10cSrcweir
660cdf0e10cSrcweir################################################################################
661cdf0e10cSrcweir# Collect all DiskIds to the corresponding cabinet files from Media.idt.
662cdf0e10cSrcweir################################################################################
663cdf0e10cSrcweir
664cdf0e10cSrcweirsub analyze_media_file
665cdf0e10cSrcweir{
666cdf0e10cSrcweir	my ($filecontent) = @_;
667cdf0e10cSrcweir
668cdf0e10cSrcweir	my %diskidhash = ();
669cdf0e10cSrcweir
670cdf0e10cSrcweir	for ( my $i = 0; $i <= $#{$filecontent}; $i++ )
671cdf0e10cSrcweir	{
672cdf0e10cSrcweir		if ( $i < 3 ) { next; }
673cdf0e10cSrcweir
674cdf0e10cSrcweir		if ( ${$filecontent}[$i] =~ /^\s*(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\s*$/ )
675cdf0e10cSrcweir		{
676cdf0e10cSrcweir			my $diskid = $1;
677cdf0e10cSrcweir			my $cabfile = $4;
678cdf0e10cSrcweir
679cdf0e10cSrcweir			$diskidhash{$cabfile} = $diskid;
680cdf0e10cSrcweir		}
681cdf0e10cSrcweir	}
682cdf0e10cSrcweir
683cdf0e10cSrcweir	return \%diskidhash;
684cdf0e10cSrcweir}
685cdf0e10cSrcweir
686cdf0e10cSrcweirsub analyze_customaction_file
687cdf0e10cSrcweir{
688cdf0e10cSrcweir	my ($filecontent) = @_;
689cdf0e10cSrcweir
690cdf0e10cSrcweir	my $register_extensions_exists = 0;
691cdf0e10cSrcweir
692cdf0e10cSrcweir	my %table = ();
693cdf0e10cSrcweir
694cdf0e10cSrcweir	for ( my $i = 0; $i <= $#{$filecontent}; $i++ )
695cdf0e10cSrcweir	{
696cdf0e10cSrcweir		if ( ${$filecontent}[$i] =~ /^\s*RegisterExtensions\s+/ )
697cdf0e10cSrcweir		{
698cdf0e10cSrcweir			$register_extensions_exists = 1;
699cdf0e10cSrcweir			last;
700cdf0e10cSrcweir		}
701cdf0e10cSrcweir	}
702cdf0e10cSrcweir
703cdf0e10cSrcweir	return $register_extensions_exists;
704cdf0e10cSrcweir}
705cdf0e10cSrcweir
706cdf0e10cSrcweir################################################################################
707cdf0e10cSrcweir# Analyzing the content of Directory.idt
708cdf0e10cSrcweir#################################################################################
709cdf0e10cSrcweir
710cdf0e10cSrcweirsub analyze_directory_file
711cdf0e10cSrcweir{
712cdf0e10cSrcweir	my ($filecontent) = @_;
713cdf0e10cSrcweir
714cdf0e10cSrcweir	my %table = ();
715cdf0e10cSrcweir
716cdf0e10cSrcweir	for ( my $i = 0; $i <= $#{$filecontent}; $i++ )
717cdf0e10cSrcweir	{
718cdf0e10cSrcweir		if (( $i == 0 ) || ( $i == 1 ) || ( $i == 2 )) { next; }
719cdf0e10cSrcweir
720cdf0e10cSrcweir		if ( ${$filecontent}[$i] =~ /^\s*(.*?)\t(.*?)\t(.*?)\s*$/ )
721cdf0e10cSrcweir		{
722cdf0e10cSrcweir			my $dir = $1;
723cdf0e10cSrcweir			my $parent = $2;
724cdf0e10cSrcweir			my $name = $3;
725cdf0e10cSrcweir
726cdf0e10cSrcweir			if ( $name =~ /^\s*(.*?)\s*\:\s*(.*?)\s*$/ ) { $name = $2; }
727cdf0e10cSrcweir			if ( $name =~ /^\s*(.*?)\s*\|\s*(.*?)\s*$/ ) { $name = $2; }
728cdf0e10cSrcweir
729cdf0e10cSrcweir			my %helphash = ();
730cdf0e10cSrcweir			$helphash{'Directory_Parent'} = $parent;
731cdf0e10cSrcweir			$helphash{'DefaultDir'} = $name;
732cdf0e10cSrcweir			$table{$dir} = \%helphash;
733cdf0e10cSrcweir		}
734cdf0e10cSrcweir	}
735cdf0e10cSrcweir
736cdf0e10cSrcweir	return \%table;
737cdf0e10cSrcweir}
738cdf0e10cSrcweir
739cdf0e10cSrcweir#################################################################################
740cdf0e10cSrcweir# Analyzing the content of Component.idt
741cdf0e10cSrcweir#################################################################################
742cdf0e10cSrcweir
743cdf0e10cSrcweirsub analyze_component_file
744cdf0e10cSrcweir{
745cdf0e10cSrcweir	my ($filecontent) = @_;
746cdf0e10cSrcweir
747cdf0e10cSrcweir	my %table = ();
748cdf0e10cSrcweir
749cdf0e10cSrcweir	for ( my $i = 0; $i <= $#{$filecontent}; $i++ )
750cdf0e10cSrcweir	{
751cdf0e10cSrcweir		if (( $i == 0 ) || ( $i == 1 ) || ( $i == 2 )) { next; }
752cdf0e10cSrcweir
753cdf0e10cSrcweir		if ( ${$filecontent}[$i] =~ /^\s*(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\s*$/ )
754cdf0e10cSrcweir		{
755cdf0e10cSrcweir			my $component = $1;
756cdf0e10cSrcweir			my $dir = $3;
757cdf0e10cSrcweir
758cdf0e10cSrcweir			$table{$component} = $dir;
759cdf0e10cSrcweir		}
760cdf0e10cSrcweir	}
761cdf0e10cSrcweir
762cdf0e10cSrcweir	return \%table;
763cdf0e10cSrcweir}
764cdf0e10cSrcweir
765cdf0e10cSrcweir#################################################################################
766cdf0e10cSrcweir# Analyzing the content of File.idt
767cdf0e10cSrcweir#################################################################################
768cdf0e10cSrcweir
769cdf0e10cSrcweirsub analyze_file_file
770cdf0e10cSrcweir{
771cdf0e10cSrcweir	my ($filecontent) = @_;
772cdf0e10cSrcweir
773cdf0e10cSrcweir	my %table = ();
774cdf0e10cSrcweir	my %fileorder = ();
775cdf0e10cSrcweir	my $maxsequence = 0;
776cdf0e10cSrcweir
777cdf0e10cSrcweir	for ( my $i = 0; $i <= $#{$filecontent}; $i++ )
778cdf0e10cSrcweir	{
779cdf0e10cSrcweir		if (( $i == 0 ) || ( $i == 1 ) || ( $i == 2 )) { next; }
780cdf0e10cSrcweir
781cdf0e10cSrcweir		if ( ${$filecontent}[$i] =~ /^\s*(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\s*$/ )
782cdf0e10cSrcweir		{
783cdf0e10cSrcweir			my $file = $1;
784cdf0e10cSrcweir			my $comp = $2;
785cdf0e10cSrcweir			my $filename = $3;
786cdf0e10cSrcweir			my $sequence = $8;
787cdf0e10cSrcweir
788cdf0e10cSrcweir			if ( $filename =~ /^\s*(.*?)\s*\|\s*(.*?)\s*$/ ) { $filename = $2; }
789cdf0e10cSrcweir
790cdf0e10cSrcweir			my %helphash = ();
791cdf0e10cSrcweir			$helphash{'Component'} = $comp;
792cdf0e10cSrcweir			$helphash{'FileName'} = $filename;
793cdf0e10cSrcweir			$helphash{'Sequence'} = $sequence;
794cdf0e10cSrcweir
795cdf0e10cSrcweir			$table{$file} = \%helphash;
796cdf0e10cSrcweir
797cdf0e10cSrcweir			$fileorder{$sequence} = $file;
798cdf0e10cSrcweir
799cdf0e10cSrcweir			if ( $sequence > $maxsequence ) { $maxsequence = $sequence; }
800cdf0e10cSrcweir		}
801cdf0e10cSrcweir	}
802cdf0e10cSrcweir
803cdf0e10cSrcweir	return (\%table, \%fileorder, $maxsequence);
804cdf0e10cSrcweir}
805cdf0e10cSrcweir
806cdf0e10cSrcweir####################################################################################
807cdf0e10cSrcweir# Recursively creating the directory tree
808cdf0e10cSrcweir####################################################################################
809cdf0e10cSrcweir
810cdf0e10cSrcweirsub create_directory_tree
811cdf0e10cSrcweir{
812cdf0e10cSrcweir	my ($parent, $pathcollector, $fulldir, $dirhash) = @_;
813cdf0e10cSrcweir
814cdf0e10cSrcweir	foreach my $dir ( keys %{$dirhash} )
815cdf0e10cSrcweir	{
816cdf0e10cSrcweir		if (( $dirhash->{$dir}->{'Directory_Parent'} eq $parent ) && ( $dirhash->{$dir}->{'DefaultDir'} ne "." ))
817cdf0e10cSrcweir		{
818cdf0e10cSrcweir			my $dirname = $dirhash->{$dir}->{'DefaultDir'};
819cdf0e10cSrcweir			# Create the directory
820cdf0e10cSrcweir			my $newdir = $fulldir . $separator . $dirname;
821cdf0e10cSrcweir			if ( ! -f $newdir ) { mkdir $newdir; }
822cdf0e10cSrcweir			# Saving in collector
823cdf0e10cSrcweir			$pathcollector->{$dir} = $newdir;
824cdf0e10cSrcweir			# Iteration
825cdf0e10cSrcweir			create_directory_tree($dir, $pathcollector, $newdir, $dirhash);
826cdf0e10cSrcweir		}
827cdf0e10cSrcweir	}
828cdf0e10cSrcweir}
829cdf0e10cSrcweir
830cdf0e10cSrcweir####################################################################################
831cdf0e10cSrcweir# Creating the directory tree
832cdf0e10cSrcweir####################################################################################
833cdf0e10cSrcweir
834cdf0e10cSrcweirsub create_directory_structure
835cdf0e10cSrcweir{
836cdf0e10cSrcweir	my ($dirhash, $targetdir) = @_;
837cdf0e10cSrcweir
838cdf0e10cSrcweir	print "Creating directories\n";
839cdf0e10cSrcweir
840cdf0e10cSrcweir	my %fullpathhash = ();
841cdf0e10cSrcweir
842cdf0e10cSrcweir	my @startparents = ("TARGETDIR", "INSTALLLOCATION");
843cdf0e10cSrcweir
844cdf0e10cSrcweir	foreach $dir (@startparents) { create_directory_tree($dir, \%fullpathhash, $targetdir, $dirhash); }
845cdf0e10cSrcweir
846cdf0e10cSrcweir	# Also adding the pathes of the startparents
847cdf0e10cSrcweir	foreach $dir (@startparents)
848cdf0e10cSrcweir	{
849cdf0e10cSrcweir		if ( ! exists($fullpathhash{$dir}) ) { $fullpathhash{$dir} = $targetdir; }
850cdf0e10cSrcweir	}
851cdf0e10cSrcweir
852cdf0e10cSrcweir	return \%fullpathhash;
853cdf0e10cSrcweir}
854cdf0e10cSrcweir
855cdf0e10cSrcweir####################################################################################
856cdf0e10cSrcweir# Cygwin: Setting privileges for files
857cdf0e10cSrcweir####################################################################################
858cdf0e10cSrcweir
859cdf0e10cSrcweirsub change_privileges
860cdf0e10cSrcweir{
861cdf0e10cSrcweir	my ($destfile, $privileges) = @_;
862cdf0e10cSrcweir
863cdf0e10cSrcweir	my $localcall = "chmod $privileges " . "\"" . $destfile . "\"";
864cdf0e10cSrcweir	system($localcall);
865cdf0e10cSrcweir}
866cdf0e10cSrcweir
867cdf0e10cSrcweir####################################################################################
868cdf0e10cSrcweir# Cygwin: Setting privileges for files recursively
869cdf0e10cSrcweir####################################################################################
870cdf0e10cSrcweir
871cdf0e10cSrcweirsub change_privileges_full
872cdf0e10cSrcweir{
873cdf0e10cSrcweir	my ($target) = @_;
874cdf0e10cSrcweir
875cdf0e10cSrcweir	print "Changing privileges\n";
876cdf0e10cSrcweir
877cdf0e10cSrcweir	my $localcall = "chmod -R 755 " . "\"" . $target . "\"";
878cdf0e10cSrcweir	system($localcall);
879cdf0e10cSrcweir}
880cdf0e10cSrcweir
881cdf0e10cSrcweir######################################################
882cdf0e10cSrcweir# Creating a new directory with defined privileges
883cdf0e10cSrcweir######################################################
884cdf0e10cSrcweir
885cdf0e10cSrcweirsub create_directory_with_privileges
886cdf0e10cSrcweir{
887cdf0e10cSrcweir	my ($directory, $privileges) = @_;
888cdf0e10cSrcweir
889cdf0e10cSrcweir	my $returnvalue = 1;
890cdf0e10cSrcweir	my $infoline = "";
891cdf0e10cSrcweir
892cdf0e10cSrcweir	if (!(-d $directory))
893cdf0e10cSrcweir	{
894cdf0e10cSrcweir		my $localprivileges = oct("0".$privileges); # changes "777" to 0777
895cdf0e10cSrcweir		$returnvalue = mkdir($directory, $localprivileges);
896cdf0e10cSrcweir
897cdf0e10cSrcweir		if ($returnvalue)
898cdf0e10cSrcweir		{
899cdf0e10cSrcweir            my $localcall = "chmod $privileges $directory \>\/dev\/null 2\>\&1";
900cdf0e10cSrcweir            system($localcall);
901cdf0e10cSrcweir		}
902cdf0e10cSrcweir	}
903cdf0e10cSrcweir	else
904cdf0e10cSrcweir	{
905cdf0e10cSrcweir        my $localcall = "chmod $privileges $directory \>\/dev\/null 2\>\&1";
906cdf0e10cSrcweir        system($localcall);
907cdf0e10cSrcweir	}
908cdf0e10cSrcweir}
909cdf0e10cSrcweir
910cdf0e10cSrcweir######################################################
911cdf0e10cSrcweir# Creating a unique directory with pid extension
912cdf0e10cSrcweir######################################################
913cdf0e10cSrcweir
914cdf0e10cSrcweirsub create_pid_directory
915cdf0e10cSrcweir{
916cdf0e10cSrcweir	my ($directory) = @_;
917cdf0e10cSrcweir
918cdf0e10cSrcweir	$directory =~ s/\Q$separator\E\s*$//;
919cdf0e10cSrcweir	my $pid = $$;			# process id
920cdf0e10cSrcweir	my $time = time();		# time
921cdf0e10cSrcweir
922cdf0e10cSrcweir	$directory = $directory . "_" . $pid . $time;
923cdf0e10cSrcweir
924cdf0e10cSrcweir	if ( ! -d $directory ) { create_directory($directory); }
925cdf0e10cSrcweir	else { exit_program("ERROR: Directory $directory already exists!"); }
926cdf0e10cSrcweir
927cdf0e10cSrcweir	return $directory;
928cdf0e10cSrcweir}
929cdf0e10cSrcweir
930cdf0e10cSrcweir####################################################################################
931cdf0e10cSrcweir# Copying files into installation set
932cdf0e10cSrcweir####################################################################################
933cdf0e10cSrcweir
934cdf0e10cSrcweirsub copy_files_into_directory_structure
935cdf0e10cSrcweir{
936cdf0e10cSrcweir	my ($fileorder, $filehash, $componenthash, $fullpathhash, $maxsequence, $unpackdir, $installdir, $dirhash) = @_;
937cdf0e10cSrcweir
938cdf0e10cSrcweir	print "Copying files\n";
939cdf0e10cSrcweir
940cdf0e10cSrcweir	my $unopkgfile = "";
941cdf0e10cSrcweir
942cdf0e10cSrcweir	for ( my $i = 1; $i <= $maxsequence; $i++ )
943cdf0e10cSrcweir	{
944cdf0e10cSrcweir		if ( exists($fileorder->{$i}) )
945cdf0e10cSrcweir		{
946cdf0e10cSrcweir			my $file = $fileorder->{$i};
947cdf0e10cSrcweir			if ( ! exists($filehash->{$file}->{'Component'}) ) { exit_program("ERROR: Did not find component for file: \"$file\"."); }
948cdf0e10cSrcweir			my $component = $filehash->{$file}->{'Component'};
949cdf0e10cSrcweir			if ( ! exists($componenthash->{$component}) ) { exit_program("ERROR: Did not find directory for component: \"$component\"."); }
950cdf0e10cSrcweir			my $dirname = $componenthash->{$component};
951cdf0e10cSrcweir			if ( ! exists($fullpathhash->{$dirname}) ) { exit_program("ERROR: Did not find full directory path for dir: \"$dirname\"."); }
952cdf0e10cSrcweir			my $destdir = $fullpathhash->{$dirname};
953cdf0e10cSrcweir			if ( ! exists($filehash->{$file}->{'FileName'}) ) { exit_program("ERROR: Did not find \"FileName\" for file: \"$file\"."); }
954cdf0e10cSrcweir			my $destfile = $filehash->{$file}->{'FileName'};
955cdf0e10cSrcweir
956cdf0e10cSrcweir			$destfile = $destdir . $separator . $destfile;
957cdf0e10cSrcweir			my $sourcefile = $unpackdir . $separator . $file;
958cdf0e10cSrcweir
959cdf0e10cSrcweir			if ( ! -f $sourcefile )
960cdf0e10cSrcweir			{
961cdf0e10cSrcweir				# It is possible, that this was an unpacked file
962cdf0e10cSrcweir				# Looking in the dirhash, to find the subdirectory in the installation set (the id is $dirname)
963cdf0e10cSrcweir				# subdir is not recursively analyzed, only one directory.
964cdf0e10cSrcweir
965cdf0e10cSrcweir				my $oldsourcefile = $sourcefile;
966cdf0e10cSrcweir				my $subdir = "";
967cdf0e10cSrcweir				if ( exists($dirhash->{$dirname}->{'DefaultDir'}) ) { $subdir = $dirhash->{$dirname}->{'DefaultDir'} . $separator; }
968cdf0e10cSrcweir				my $realfilename = $filehash->{$file}->{'FileName'};
969cdf0e10cSrcweir				my $localinstalldir = $installdir;
970cdf0e10cSrcweir
971cdf0e10cSrcweir				$localinstalldir =~ s/\\\s*$//;
972cdf0e10cSrcweir				$localinstalldir =~ s/\/\s*$//;
973cdf0e10cSrcweir
974cdf0e10cSrcweir				$sourcefile = $localinstalldir . $separator . $subdir . $realfilename;
975cdf0e10cSrcweir
976cdf0e10cSrcweir				if ( ! -f $sourcefile ) { exit_program("ERROR: File not found: \"$oldsourcefile\" (or \"$sourcefile\")."); }
977cdf0e10cSrcweir			}
978cdf0e10cSrcweir
979cdf0e10cSrcweir			my $copyreturn = copy($sourcefile, $destfile);
980cdf0e10cSrcweir
981cdf0e10cSrcweir			if ( ! $copyreturn) { exit_program("ERROR: Could not copy $source to $dest\n"); }
982cdf0e10cSrcweir
983cdf0e10cSrcweir			# Searching unopkg.exe
984cdf0e10cSrcweir			if ( $destfile =~ /unopkg\.exe\s*$/ ) { $unopkgfile = $destfile; }
985cdf0e10cSrcweir			# if (( $^O =~ /cygwin/i ) && ( $destfile =~ /\.exe\s*$/ )) { change_privileges($destfile, "775"); }
986cdf0e10cSrcweir		}
987cdf0e10cSrcweir		# else	# allowing missing sequence numbers ?
988cdf0e10cSrcweir		# {
989cdf0e10cSrcweir		# 	exit_program("ERROR: No file assigned to sequence $i");
990cdf0e10cSrcweir		# }
991cdf0e10cSrcweir	}
992cdf0e10cSrcweir
993cdf0e10cSrcweir	return ($unopkgfile);
994cdf0e10cSrcweir}
995cdf0e10cSrcweir
996cdf0e10cSrcweir######################################################
997cdf0e10cSrcweir# Removing a complete directory with subdirectories
998cdf0e10cSrcweir######################################################
999cdf0e10cSrcweir
1000cdf0e10cSrcweirsub remove_complete_directory
1001cdf0e10cSrcweir{
1002cdf0e10cSrcweir	my ($directory, $start) = @_;
1003cdf0e10cSrcweir
1004cdf0e10cSrcweir	my @content = ();
1005cdf0e10cSrcweir	my $infoline = "";
1006cdf0e10cSrcweir
1007cdf0e10cSrcweir	$directory =~ s/\Q$separator\E\s*$//;
1008cdf0e10cSrcweir
1009cdf0e10cSrcweir	if ( -d $directory )
1010cdf0e10cSrcweir	{
1011cdf0e10cSrcweir		if ( $start ) { print "Removing directory $directory\n"; }
1012cdf0e10cSrcweir
1013cdf0e10cSrcweir		opendir(DIR, $directory);
1014cdf0e10cSrcweir		@content = readdir(DIR);
1015cdf0e10cSrcweir		closedir(DIR);
1016cdf0e10cSrcweir
1017cdf0e10cSrcweir		my $oneitem;
1018cdf0e10cSrcweir
1019cdf0e10cSrcweir		foreach $oneitem (@content)
1020cdf0e10cSrcweir		{
1021cdf0e10cSrcweir			if ((!($oneitem eq ".")) && (!($oneitem eq "..")))
1022cdf0e10cSrcweir			{
1023cdf0e10cSrcweir				my $item = $directory . $separator . $oneitem;
1024cdf0e10cSrcweir
1025cdf0e10cSrcweir				if ( -f $item || -l $item ) 	# deleting files or links
1026cdf0e10cSrcweir				{
1027cdf0e10cSrcweir					unlink($item);
1028cdf0e10cSrcweir				}
1029cdf0e10cSrcweir
1030cdf0e10cSrcweir				if ( -d $item ) 	# recursive
1031cdf0e10cSrcweir				{
1032cdf0e10cSrcweir					remove_complete_directory($item, 0);
1033cdf0e10cSrcweir				}
1034cdf0e10cSrcweir			}
1035cdf0e10cSrcweir		}
1036cdf0e10cSrcweir
1037cdf0e10cSrcweir		# try to remove empty directory
1038cdf0e10cSrcweir		my $returnvalue = rmdir $directory;
1039cdf0e10cSrcweir		if ( ! $returnvalue ) { print "Warning: Problem with removing empty dir $directory\n"; }
1040cdf0e10cSrcweir	}
1041cdf0e10cSrcweir}
1042cdf0e10cSrcweir
1043cdf0e10cSrcweir####################################################################################
1044cdf0e10cSrcweir# Defining a temporary path
1045cdf0e10cSrcweir####################################################################################
1046cdf0e10cSrcweir
1047cdf0e10cSrcweirsub get_temppath
1048cdf0e10cSrcweir{
1049cdf0e10cSrcweir	my $temppath = "";
1050cdf0e10cSrcweir
1051cdf0e10cSrcweir	if (( $ENV{'TMP'} ) || ( $ENV{'TEMP'} ))
1052cdf0e10cSrcweir	{
1053cdf0e10cSrcweir		if ( $ENV{'TMP'} ) { $temppath = $ENV{'TMP'}; }
1054cdf0e10cSrcweir		elsif ( $ENV{'TEMP'} )  { $temppath = $ENV{'TEMP'}; }
1055cdf0e10cSrcweir
1056cdf0e10cSrcweir		$temppath =~ s/\Q$separator\E\s*$//;	# removing ending slashes and backslashes
1057cdf0e10cSrcweir		$temppath = $temppath . $separator . $globaltempdirname;
1058cdf0e10cSrcweir		create_directory_with_privileges($temppath, "777");
1059cdf0e10cSrcweir
1060cdf0e10cSrcweir		my $dirsave = $temppath;
1061cdf0e10cSrcweir
1062cdf0e10cSrcweir		$temppath = $temppath . $separator . "a";
1063cdf0e10cSrcweir		$temppath = create_pid_directory($temppath);
1064cdf0e10cSrcweir
1065cdf0e10cSrcweir		if ( ! -d $temppath ) { exit_program("ERROR: Failed to create directory $temppath ! Possible reason: Wrong privileges in directory $dirsave."); }
1066cdf0e10cSrcweir
1067cdf0e10cSrcweir		if ( $^O =~ /cygwin/i )
1068cdf0e10cSrcweir		{
1069cdf0e10cSrcweir			$temppath =~ s/\\/\\\\/g;
1070cdf0e10cSrcweir			chomp( $temppath = qx{cygpath -w "$temppath"} );
1071cdf0e10cSrcweir		}
1072cdf0e10cSrcweir
1073cdf0e10cSrcweir		$savetemppath = $temppath;
1074cdf0e10cSrcweir	}
1075cdf0e10cSrcweir	else
1076cdf0e10cSrcweir	{
1077cdf0e10cSrcweir		exit_program("ERROR: Could not set temporary directory (TMP and TEMP not set!).");
1078cdf0e10cSrcweir	}
1079cdf0e10cSrcweir
1080cdf0e10cSrcweir	return $temppath;
1081cdf0e10cSrcweir}
1082cdf0e10cSrcweir
1083cdf0e10cSrcweir####################################################################################
1084cdf0e10cSrcweir# Registering extensions
1085cdf0e10cSrcweir####################################################################################
1086cdf0e10cSrcweir
1087cdf0e10cSrcweirsub register_extensions_sync
1088cdf0e10cSrcweir{
1089cdf0e10cSrcweir	my ($unopkgfile, $localtemppath, $preregdir) = @_;
1090cdf0e10cSrcweir
1091cdf0e10cSrcweir	if ( $preregdir eq "" )
1092cdf0e10cSrcweir	{
1093cdf0e10cSrcweir		my $logtext = "ERROR: Failed to determine \"prereg\" folder for extension registration! Please check your installation set.";
1094cdf0e10cSrcweir		print $logtext . "\n";
1095cdf0e10cSrcweir		exit_program($logtext);
1096cdf0e10cSrcweir	}
1097cdf0e10cSrcweir
1098cdf0e10cSrcweir	my $from = cwd();
1099cdf0e10cSrcweir
1100cdf0e10cSrcweir	my $path = $unopkgfile;
1101cdf0e10cSrcweir	get_path_from_fullqualifiedname(\$path);
1102cdf0e10cSrcweir	$path =~ s/\\\s*$//;
1103cdf0e10cSrcweir	$path =~ s/\/\s*$//;
1104cdf0e10cSrcweir
1105cdf0e10cSrcweir	my $executable = $unopkgfile;
1106cdf0e10cSrcweir	make_absolute_filename_to_relative_filename(\$executable);
1107cdf0e10cSrcweir
1108cdf0e10cSrcweir	chdir($path);
1109cdf0e10cSrcweir
1110cdf0e10cSrcweir	if ( ! $path_displayed )
1111cdf0e10cSrcweir	{
1112cdf0e10cSrcweir		print "... current dir: $path ...\n";
1113cdf0e10cSrcweir		$path_displayed = 1;
1114cdf0e10cSrcweir	}
1115cdf0e10cSrcweir
1116cdf0e10cSrcweir	$localtemppath =~ s/\\/\//g;
1117cdf0e10cSrcweir
1118cdf0e10cSrcweir	if ( $^O =~ /cygwin/i ) {
1119cdf0e10cSrcweir		$executable = "./" . $executable;
1120cdf0e10cSrcweir		$preregdir = qx{cygpath -m "$preregdir"};
1121cdf0e10cSrcweir		chomp($preregdir);
1122cdf0e10cSrcweir	}
1123cdf0e10cSrcweir
1124cdf0e10cSrcweir	$preregdir =~ s/\/\s*$//g;
1125cdf0e10cSrcweir
1126cdf0e10cSrcweir	my $systemcall = $executable . " sync --verbose 2\>\&1 |";
1127cdf0e10cSrcweir
1128cdf0e10cSrcweir	print "... $systemcall\n";
1129cdf0e10cSrcweir
1130cdf0e10cSrcweir	my @unopkgoutput = ();
1131cdf0e10cSrcweir
1132cdf0e10cSrcweir	open (UNOPKG, $systemcall);
1133cdf0e10cSrcweir	while (<UNOPKG>) {push(@unopkgoutput, $_); }
1134cdf0e10cSrcweir	close (UNOPKG);
1135cdf0e10cSrcweir
1136cdf0e10cSrcweir	my $returnvalue = $?;	# $? contains the return value of the systemcall
1137cdf0e10cSrcweir
1138cdf0e10cSrcweir	if ($returnvalue)
1139cdf0e10cSrcweir	{
1140cdf0e10cSrcweir		print "ERROR: Could not execute \"$systemcall\"!\nExitcode: '$returnvalue'\n";
1141cdf0e10cSrcweir		for ( my $j = 0; $j <= $#unopkgoutput; $j++ ) { print "$unopkgoutput[$j]"; }
1142cdf0e10cSrcweir		exit_program("ERROR: $systemcall failed!");
1143cdf0e10cSrcweir	}
1144cdf0e10cSrcweir
1145cdf0e10cSrcweir	chdir($from);
1146cdf0e10cSrcweir}
1147cdf0e10cSrcweir
1148cdf0e10cSrcweir####################################################################################
1149cdf0e10cSrcweir# Registering all extensions located in /share/extension/install
1150cdf0e10cSrcweir####################################################################################
1151cdf0e10cSrcweir
1152cdf0e10cSrcweirsub register_extensions
1153cdf0e10cSrcweir{
1154cdf0e10cSrcweir	my ($unopkgfile, $temppath, $preregdir) = @_;
1155cdf0e10cSrcweir
1156cdf0e10cSrcweir	print "Registering extensions:\n";
1157cdf0e10cSrcweir
1158cdf0e10cSrcweir	if (( ! -f $unopkgfile ) || ( $unopkgfile eq "" ))
1159cdf0e10cSrcweir	{
1160cdf0e10cSrcweir		print("WARNING: Could not find unopkg.exe (Language Pack?)!\n");
1161cdf0e10cSrcweir	}
1162cdf0e10cSrcweir	else
1163cdf0e10cSrcweir	{
1164cdf0e10cSrcweir		register_extensions_sync($unopkgfile, $temppath, $preregdir);
1165cdf0e10cSrcweir		remove_complete_directory($temppath, 1);
1166cdf0e10cSrcweir	}
1167cdf0e10cSrcweir
1168cdf0e10cSrcweir}
1169cdf0e10cSrcweir
1170cdf0e10cSrcweir####################################################################################
1171cdf0e10cSrcweir# Reading one file
1172cdf0e10cSrcweir####################################################################################
1173cdf0e10cSrcweir
1174cdf0e10cSrcweirsub read_file
1175cdf0e10cSrcweir{
1176cdf0e10cSrcweir	my ($localfile) = @_;
1177cdf0e10cSrcweir
1178cdf0e10cSrcweir	my @localfile = ();
1179cdf0e10cSrcweir
1180cdf0e10cSrcweir	open( IN, "<$localfile" ) || exit_program("ERROR: Cannot open file $localfile for reading");
1181cdf0e10cSrcweir
1182cdf0e10cSrcweir	#	Don't use "my @localfile = <IN>" here, because
1183cdf0e10cSrcweir	#	perl has a problem with the internal "large_and_huge_malloc" function
1184cdf0e10cSrcweir	#	when calling perl using MacOS 10.5 with a perl built with MacOS 10.4
1185cdf0e10cSrcweir	while ( $line = <IN> ) {
1186cdf0e10cSrcweir		push @localfile, $line;
1187cdf0e10cSrcweir	}
1188cdf0e10cSrcweir
1189cdf0e10cSrcweir	close( IN );
1190cdf0e10cSrcweir
1191cdf0e10cSrcweir	return \@localfile;
1192cdf0e10cSrcweir}
1193cdf0e10cSrcweir
1194cdf0e10cSrcweir###############################################################
1195cdf0e10cSrcweir# Setting the time string for the
1196cdf0e10cSrcweir# Summary Information stream in the
1197cdf0e10cSrcweir# msi database of the admin installations.
1198cdf0e10cSrcweir###############################################################
1199cdf0e10cSrcweir
1200cdf0e10cSrcweirsub get_sis_time_string
1201cdf0e10cSrcweir{
1202cdf0e10cSrcweir	# Syntax: <yyyy/mm/dd hh:mm:ss>
1203cdf0e10cSrcweir	my $second = (localtime())[0];
1204cdf0e10cSrcweir	my $minute = (localtime())[1];
1205cdf0e10cSrcweir	my $hour = (localtime())[2];
1206cdf0e10cSrcweir	my $day = (localtime())[3];
1207cdf0e10cSrcweir	my $month = (localtime())[4];
1208cdf0e10cSrcweir	my $year = 1900 + (localtime())[5];
1209cdf0e10cSrcweir    $month++;
1210cdf0e10cSrcweir
1211cdf0e10cSrcweir	if ( $second < 10 ) { $second = "0" . $second; }
1212cdf0e10cSrcweir	if ( $minute < 10 ) { $minute = "0" . $minute; }
1213cdf0e10cSrcweir	if ( $hour < 10 ) { $hour = "0" . $hour; }
1214cdf0e10cSrcweir	if ( $day < 10 ) { $day = "0" . $day; }
1215cdf0e10cSrcweir	if ( $month < 10 ) { $month = "0" . $month; }
1216cdf0e10cSrcweir
1217cdf0e10cSrcweir	my $timestring = $year . "/" . $month . "/" . $day . " " . $hour . ":" . $minute . ":" . $second;
1218cdf0e10cSrcweir
1219cdf0e10cSrcweir	return $timestring;
1220cdf0e10cSrcweir}
1221cdf0e10cSrcweir
1222cdf0e10cSrcweir###############################################################
1223cdf0e10cSrcweir# Writing content of administrative installations into
1224cdf0e10cSrcweir# Summary Information Stream of msi database.
1225cdf0e10cSrcweir# This is required for example for following
1226cdf0e10cSrcweir# patch processes using Windows Installer service.
1227cdf0e10cSrcweir###############################################################
1228cdf0e10cSrcweir
1229cdf0e10cSrcweirsub write_sis_info
1230cdf0e10cSrcweir{
1231cdf0e10cSrcweir	my ($msidatabase) = @_;
1232cdf0e10cSrcweir
1233cdf0e10cSrcweir	print "Setting SIS in msi database\n";
1234cdf0e10cSrcweir
1235cdf0e10cSrcweir	if ( ! -f $msidatabase ) { exit_program("ERROR: Cannot find file $msidatabase"); }
1236cdf0e10cSrcweir
1237cdf0e10cSrcweir	my $msiinfo = "msiinfo.exe";	# Has to be in the path
1238cdf0e10cSrcweir	my $infoline = "";
1239cdf0e10cSrcweir	my $systemcall = "";
1240cdf0e10cSrcweir	my $returnvalue = "";
1241cdf0e10cSrcweir
1242cdf0e10cSrcweir	# Required setting for administrative installations:
1243cdf0e10cSrcweir	# -w 4   (source files are unpacked),  wordcount
1244cdf0e10cSrcweir	# -s <date of admin installation>, LastPrinted, Syntax: <yyyy/mm/dd hh:mm:ss>
1245cdf0e10cSrcweir	# -l <person_making_admin_installation>, LastSavedBy
1246cdf0e10cSrcweir
1247cdf0e10cSrcweir	my $wordcount = 4;  # Unpacked files
1248cdf0e10cSrcweir	my $lastprinted = get_sis_time_string();
1249cdf0e10cSrcweir	my $lastsavedby = "Installer";
1250cdf0e10cSrcweir
1251cdf0e10cSrcweir	my $localmsidatabase = $msidatabase;
1252cdf0e10cSrcweir
1253cdf0e10cSrcweir	if( $^O =~ /cygwin/i )
1254cdf0e10cSrcweir	{
1255cdf0e10cSrcweir		$localmsidatabase = qx{cygpath -w "$localmsidatabase"};
1256cdf0e10cSrcweir		$localmsidatabase =~ s/\\/\\\\/g;
1257cdf0e10cSrcweir		$localmsidatabase =~ s/\s*$//g;
1258cdf0e10cSrcweir	}
1259cdf0e10cSrcweir
1260cdf0e10cSrcweir	$systemcall = $msiinfo . " " . "\"" . $localmsidatabase . "\"" . " -w " . $wordcount . " -s " . "\"" . $lastprinted . "\"" . " -l $lastsavedby";
1261cdf0e10cSrcweir
1262cdf0e10cSrcweir	$returnvalue = system($systemcall);
1263cdf0e10cSrcweir
1264cdf0e10cSrcweir	if ($returnvalue)
1265cdf0e10cSrcweir	{
1266cdf0e10cSrcweir		$infoline = "ERROR: Could not execute $systemcall !\n";
1267cdf0e10cSrcweir		exit_program($infoline);
1268cdf0e10cSrcweir	}
1269cdf0e10cSrcweir}
1270cdf0e10cSrcweir
1271cdf0e10cSrcweir###############################################################
1272cdf0e10cSrcweir# Convert time string
1273cdf0e10cSrcweir###############################################################
1274cdf0e10cSrcweir
1275cdf0e10cSrcweirsub convert_timestring
1276cdf0e10cSrcweir{
1277cdf0e10cSrcweir	my ($secondstring) = @_;
1278cdf0e10cSrcweir
1279cdf0e10cSrcweir	my $timestring = "";
1280cdf0e10cSrcweir
1281cdf0e10cSrcweir	if ( $secondstring < 60 )	 # less than a minute
1282cdf0e10cSrcweir	{
1283cdf0e10cSrcweir		if ( $secondstring < 10 ) { $secondstring = "0" . $secondstring; }
1284cdf0e10cSrcweir		$timestring = "00\:$secondstring min\.";
1285cdf0e10cSrcweir	}
1286cdf0e10cSrcweir	elsif ( $secondstring < 3600 )
1287cdf0e10cSrcweir	{
1288cdf0e10cSrcweir		my $minutes = $secondstring / 60;
1289cdf0e10cSrcweir		my $seconds = $secondstring % 60;
1290cdf0e10cSrcweir		if ( $minutes =~ /(\d*)\.\d*/ ) { $minutes = $1; }
1291cdf0e10cSrcweir		if ( $minutes < 10 ) { $minutes = "0" . $minutes; }
1292cdf0e10cSrcweir		if ( $seconds < 10 ) { $seconds = "0" . $seconds; }
1293cdf0e10cSrcweir		$timestring = "$minutes\:$seconds min\.";
1294cdf0e10cSrcweir	}
1295cdf0e10cSrcweir	else	# more than one hour
1296cdf0e10cSrcweir	{
1297cdf0e10cSrcweir		my $hours = $secondstring / 3600;
1298cdf0e10cSrcweir		my $secondstring = $secondstring % 3600;
1299cdf0e10cSrcweir		my $minutes = $secondstring / 60;
1300cdf0e10cSrcweir		my $seconds = $secondstring % 60;
1301cdf0e10cSrcweir		if ( $hours =~ /(\d*)\.\d*/ ) { $hours = $1; }
1302cdf0e10cSrcweir		if ( $minutes =~ /(\d*)\.\d*/ ) { $minutes = $1; }
1303cdf0e10cSrcweir		if ( $hours < 10 ) { $hours = "0" . $hours; }
1304cdf0e10cSrcweir		if ( $minutes < 10 ) { $minutes = "0" . $minutes; }
1305cdf0e10cSrcweir		if ( $seconds < 10 ) { $seconds = "0" . $seconds; }
1306cdf0e10cSrcweir		$timestring = "$hours\:$minutes\:$seconds hours";
1307cdf0e10cSrcweir	}
1308cdf0e10cSrcweir
1309cdf0e10cSrcweir	return $timestring;
1310cdf0e10cSrcweir}
1311cdf0e10cSrcweir
1312cdf0e10cSrcweir###############################################################
1313cdf0e10cSrcweir# Returning time string for logging
1314cdf0e10cSrcweir###############################################################
1315cdf0e10cSrcweir
1316cdf0e10cSrcweirsub get_time_string
1317cdf0e10cSrcweir{
1318cdf0e10cSrcweir	my $currenttime = time();
1319cdf0e10cSrcweir	$currenttime = $currenttime - $starttime;
1320cdf0e10cSrcweir	$currenttime = convert_timestring($currenttime);
1321cdf0e10cSrcweir	$currenttime = localtime() . " \(" . $currenttime . "\)\n";
1322cdf0e10cSrcweir	return $currenttime;
1323cdf0e10cSrcweir}
1324cdf0e10cSrcweir
1325cdf0e10cSrcweir####################################################################################
1326cdf0e10cSrcweir# Simulating an administrative installation
1327cdf0e10cSrcweir####################################################################################
1328cdf0e10cSrcweir
1329cdf0e10cSrcweir$starttime = time();
1330cdf0e10cSrcweir
1331cdf0e10cSrcweirgetparameter();
1332cdf0e10cSrcweircontrolparameter();
1333cdf0e10cSrcweircheck_local_msidb();
1334cdf0e10cSrcweircheck_system_path();
1335cdf0e10cSrcweirmy $temppath = get_temppath();
1336cdf0e10cSrcweir
1337cdf0e10cSrcweirprint("\nmsi database: $databasepath\n");
1338cdf0e10cSrcweirprint("Destination directory: $targetdir\n" );
1339cdf0e10cSrcweir
1340cdf0e10cSrcweirmy $helperdir = $temppath . $separator . "installhelper";
1341cdf0e10cSrcweircreate_directory($helperdir);
1342cdf0e10cSrcweir
1343cdf0e10cSrcweir# Get File.idt, Component.idt and Directory.idt from database
1344cdf0e10cSrcweir
1345cdf0e10cSrcweirmy $tablelist = "File Directory Component Media CustomAction";
1346cdf0e10cSrcweirextract_tables_from_database($databasepath, $helperdir, $tablelist);
1347cdf0e10cSrcweir
1348cdf0e10cSrcweir# Set unpackdir
1349cdf0e10cSrcweirmy $unpackdir = $helperdir . $separator . "unpack";
1350cdf0e10cSrcweircreate_directory($unpackdir);
1351cdf0e10cSrcweir
1352cdf0e10cSrcweir# Reading media table to check for internal cabinet files
1353cdf0e10cSrcweirmy $filename = $helperdir . $separator . "Media.idt";
1354cdf0e10cSrcweirif ( ! -f $filename ) { exit_program("ERROR: Could not find required file: $filename !"); }
1355cdf0e10cSrcweirmy $filecontent = read_file($filename);
1356cdf0e10cSrcweirmy $cabfilehash = analyze_media_file($filecontent);
1357cdf0e10cSrcweir
1358cdf0e10cSrcweir# Check, if there are internal cab files
1359cdf0e10cSrcweirmy ( $contains_internal_cabfiles, $all_internal_cab_files) = check_for_internal_cabfiles($cabfilehash);
1360cdf0e10cSrcweir
1361cdf0e10cSrcweirif ( $contains_internal_cabfiles )
1362cdf0e10cSrcweir{
1363cdf0e10cSrcweir	# Set unpackdir
1364cdf0e10cSrcweir	my $cabdir = $helperdir . $separator . "internal_cabs";
1365cdf0e10cSrcweir	create_directory($cabdir);
1366cdf0e10cSrcweir	my $from = cwd();
1367cdf0e10cSrcweir	chdir($cabdir);
1368cdf0e10cSrcweir	# Exclude all cabinet files from database
1369cdf0e10cSrcweir	my $all_excluded_cabs = extract_cabs_from_database($databasepath, $all_internal_cab_files);
1370cdf0e10cSrcweir	print "Unpacking files from internal cabinet file(s)\n";
1371cdf0e10cSrcweir	foreach my $cabfile ( @{$all_excluded_cabs} ) { unpack_cabinet_file($cabfile, $unpackdir); }
1372cdf0e10cSrcweir	chdir($from);
1373cdf0e10cSrcweir}
1374cdf0e10cSrcweir
1375cdf0e10cSrcweir# Unpack all cab files into $helperdir, cab files must be located next to msi database
1376cdf0e10cSrcweirmy $installdir = $databasepath;
1377cdf0e10cSrcweir
1378cdf0e10cSrcweirget_path_from_fullqualifiedname(\$installdir);
1379cdf0e10cSrcweir
1380cdf0e10cSrcweirmy $databasefilename = $databasepath;
1381cdf0e10cSrcweirmake_absolute_filename_to_relative_filename(\$databasefilename);
1382cdf0e10cSrcweir
1383cdf0e10cSrcweirmy $cabfiles = find_file_with_file_extension("cab", $installdir);
1384cdf0e10cSrcweir
1385cdf0e10cSrcweirif (( $#{$cabfiles} < 0 ) && ( ! $contains_internal_cabfiles )) { exit_program("ERROR: Did not find any cab file in directory $installdir"); }
1386cdf0e10cSrcweir
1387cdf0e10cSrcweirprint "Unpacking files from cabinet file(s)\n";
1388cdf0e10cSrcweirfor ( my $i = 0; $i <= $#{$cabfiles}; $i++ )
1389cdf0e10cSrcweir{
1390cdf0e10cSrcweir	my $cabfile = $installdir . $separator . ${$cabfiles}[$i];
1391cdf0e10cSrcweir	unpack_cabinet_file($cabfile, $unpackdir);
1392cdf0e10cSrcweir}
1393cdf0e10cSrcweir
1394cdf0e10cSrcweir# Reading tables
1395cdf0e10cSrcweir$filename = $helperdir . $separator . "Directory.idt";
1396cdf0e10cSrcweir$filecontent = read_file($filename);
1397cdf0e10cSrcweirmy $dirhash = analyze_directory_file($filecontent);
1398cdf0e10cSrcweir
1399cdf0e10cSrcweir$filename = $helperdir . $separator . "Component.idt";
1400cdf0e10cSrcweir$filecontent = read_file($filename);
1401cdf0e10cSrcweirmy $componenthash = analyze_component_file($filecontent);
1402cdf0e10cSrcweir
1403cdf0e10cSrcweir$filename = $helperdir . $separator . "File.idt";
1404cdf0e10cSrcweir$filecontent = read_file($filename);
1405cdf0e10cSrcweirmy ( $filehash, $fileorder, $maxsequence ) = analyze_file_file($filecontent);
1406cdf0e10cSrcweir
1407cdf0e10cSrcweir# Creating the directory structure
1408cdf0e10cSrcweirmy $fullpathhash = create_directory_structure($dirhash, $targetdir);
1409cdf0e10cSrcweir
1410cdf0e10cSrcweir# Copying files
1411cdf0e10cSrcweirmy ($unopkgfile) = copy_files_into_directory_structure($fileorder, $filehash, $componenthash, $fullpathhash, $maxsequence, $unpackdir, $installdir, $dirhash);
1412cdf0e10cSrcweirif ( $^O =~ /cygwin/i ) { change_privileges_full($targetdir); }
1413cdf0e10cSrcweir
1414cdf0e10cSrcweirmy $msidatabase = $targetdir . $separator . $databasefilename;
1415cdf0e10cSrcweirmy $copyreturn = copy($databasepath, $msidatabase);
1416cdf0e10cSrcweirif ( ! $copyreturn) { exit_program("ERROR: Could not copy $source to $dest\n"); }
1417cdf0e10cSrcweir
1418cdf0e10cSrcweir# Reading tables
1419cdf0e10cSrcweir$filename = $helperdir . $separator . "CustomAction.idt";
1420cdf0e10cSrcweir$filecontent = read_file($filename);
1421cdf0e10cSrcweirmy $register_extensions_exists = analyze_customaction_file($filecontent);
1422cdf0e10cSrcweir
1423cdf0e10cSrcweir# Removing empty dirs in extension folder
1424cdf0e10cSrcweirmy ( $extensionfolder, $preregdir ) = get_extensions_dir($unopkgfile);
1425cdf0e10cSrcweirif ( -d $extensionfolder ) { remove_empty_dirs_in_folder($extensionfolder, 1); }
1426cdf0e10cSrcweir
1427cdf0e10cSrcweirif ( $register_extensions_exists )
1428cdf0e10cSrcweir{
1429cdf0e10cSrcweir	# Registering extensions
1430cdf0e10cSrcweir	register_extensions($unopkgfile, $temppath, $preregdir);
1431cdf0e10cSrcweir}
1432cdf0e10cSrcweir
1433cdf0e10cSrcweir# Saving info in Summary Information Stream of msi database (required for following patches)
1434cdf0e10cSrcweirif ( $msiinfo_available ) { write_sis_info($msidatabase); }
1435cdf0e10cSrcweir
1436cdf0e10cSrcweir# Removing the helper directory
1437cdf0e10cSrcweirremove_complete_directory($temppath, 1);
1438cdf0e10cSrcweir
1439cdf0e10cSrcweirprint "\nSuccessful installation: " . get_time_string();
1440