xref: /trunk/main/setup_native/scripts/admin.pl (revision 95e2fe77240256cfc0711c47019d8b74a6327be0)
17e90fac2SAndrew Rist#**************************************************************
2cdf0e10cSrcweir#
37e90fac2SAndrew Rist#  Licensed to the Apache Software Foundation (ASF) under one
47e90fac2SAndrew Rist#  or more contributor license agreements.  See the NOTICE file
57e90fac2SAndrew Rist#  distributed with this work for additional information
67e90fac2SAndrew Rist#  regarding copyright ownership.  The ASF licenses this file
77e90fac2SAndrew Rist#  to you under the Apache License, Version 2.0 (the
87e90fac2SAndrew Rist#  "License"); you may not use this file except in compliance
97e90fac2SAndrew Rist#  with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir#
117e90fac2SAndrew Rist#    http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir#
137e90fac2SAndrew Rist#  Unless required by applicable law or agreed to in writing,
147e90fac2SAndrew Rist#  software distributed under the License is distributed on an
157e90fac2SAndrew Rist#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
167e90fac2SAndrew Rist#  KIND, either express or implied.  See the License for the
177e90fac2SAndrew Rist#  specific language governing permissions and limitations
187e90fac2SAndrew Rist#  under the License.
19cdf0e10cSrcweir#
207e90fac2SAndrew Rist#**************************************************************
217e90fac2SAndrew Rist
227e90fac2SAndrew 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";
94*95e2fe77Smseidel            print "Error: Unknown 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
14686e1cf34SPedro Giffuni# not necessary 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##########################################################################
26686e1cf34SPedro Giffuni# Searching a file in a list of paths
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
84686e1cf34SPedro Giffuni    # Also adding the paths 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