diff options
Diffstat (limited to '')
-rw-r--r-- | setup_native/scripts/admin.pl | 1244 | ||||
-rw-r--r-- | setup_native/scripts/fake-db.spec | 57 | ||||
-rw-r--r-- | setup_native/scripts/install_create.pl | 60 | ||||
-rw-r--r-- | setup_native/scripts/install_linux.sh | 311 | ||||
-rw-r--r-- | setup_native/scripts/langpackscript.sh | 169 | ||||
-rw-r--r-- | setup_native/scripts/mac_install.script | 27 | ||||
-rw-r--r-- | setup_native/scripts/osx_install_languagepack.applescript | 174 | ||||
-rw-r--r-- | setup_native/scripts/uninstall_linux.sh | 72 | ||||
-rw-r--r-- | setup_native/scripts/unpack_update.sh | 50 |
9 files changed, 2164 insertions, 0 deletions
diff --git a/setup_native/scripts/admin.pl b/setup_native/scripts/admin.pl new file mode 100644 index 000000000..714da400c --- /dev/null +++ b/setup_native/scripts/admin.pl @@ -0,0 +1,1244 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + +use Cwd; +use File::Copy; +use File::Temp qw/ :mktemp /; + +################################################################################# +# Global settings +################################################################################# + +BEGIN +{ + $prog = "msi installer"; + $targetdir = ""; + $databasepath = ""; + $starttime = ""; + $globaltempdirname = "ooopackagingXXXXXX"; + $savetemppath = ""; + $msiinfo_available = 0; + $path_displayed = 0; + $localmsidbpath = ""; + + $plat = $^O; + + if ( $plat =~ /cygwin/i ) + { + $separator = "/"; + $pathseparator = "\:"; + } + else + { + $separator = "\\"; + $pathseparator = "\;"; + } +} + +################################################################################# +# Program information +################################################################################# + +sub usage +{ + print <<End; +---------------------------------------------------------------------- +This program installs a Windows Installer installation set +without using msiexec.exe. The installation is comparable +with an administrative installation using the Windows Installer +service. +Required parameter: +-d Path to installation set or msi database +-t Target directory +--------------------------------------------------------------------- +End + exit(-1); +} + +################################################################################# +# Collecting parameter +################################################################################# + +sub getparameter +{ + if (( $#ARGV < 3 ) || ( $#ARGV > 3 )) { usage(); } + + while ( $#ARGV >= 0 ) + { + my $param = shift(@ARGV); + + if ($param eq "-t") { $targetdir = shift(@ARGV); } + elsif ($param eq "-d") { $databasepath = shift(@ARGV); } + else + { + print "\n**********************************************\n"; + print "Error: Unknown parameter: $param"; + print "\n**********************************************\n"; + usage(); + exit(-1); + } + } +} + +################################################################################# +# Checking content of parameter +################################################################################# + +sub controlparameter +{ + if ( $targetdir eq "" ) + { + print "\n******************************************************\n"; + print "Error: Target directory not defined (parameter -t)!"; + print "\n******************************************************\n"; + usage(); + exit(-1); + } + + if ( $databasepath eq "" ) + { + print "\n******************************************************\n"; + print "Error: Path to msi database not defined (parameter -d)!"; + print "\n******************************************************\n"; + usage(); + exit(-1); + } + + if ( -d $databasepath ) + { + $databasepath =~ s/\\\s*$//; + $databasepath =~ s/\/\s*$//; + + my $msifiles = find_file_with_file_extension("msi", $databasepath); + + if ( $#{$msifiles} < 0 ) { exit_program("ERROR: Did not find msi database in directory $installationdir"); } + if ( $#{$msifiles} > 0 ) { exit_program("ERROR: Did find more than one msi database in directory $installationdir"); } + + $databasepath = $databasepath . $separator . ${$msifiles}[0]; + } + + if ( ! -f $databasepath ) { exit_program("ERROR: Did not find msi database in directory $databasepath."); } + + if ( ! -d $targetdir ) { create_directories($targetdir); } +} + +############################################################################# +# The program msidb.exe can be located next to the Perl program. Then it is +# not necessary to find it in the PATH variable. +############################################################################# + +sub check_local_msidb +{ + my $msidbname = "msidb.exe"; + my $perlprogramm = $0; + my $path = $perlprogramm; + + get_path_from_fullqualifiedname(\$path); + + $path =~ s/\\\s*$//; + $path =~ s/\/\s*$//; + + my $msidbpath = ""; + if ( $path =~ /^\s*$/ ) { $msidbpath = $msidbname; } + else { $msidbpath = $path . $separator . $msidbname; } + + if ( -f $msidbpath ) + { + $localmsidbpath = $msidbpath; + print "Using $msidbpath (next to \"admin.pl\")\n"; + } +} + +############################################################################# +# Converting a string list with separator $listseparator +# into an array +############################################################################# + +sub convert_stringlist_into_array +{ + my ( $includestringref, $listseparator ) = @_; + + my @newarray = (); + my $first; + my $last = ${$includestringref}; + + while ( $last =~ /^\s*(.+?)\Q$listseparator\E(.+)\s*$/) # "$" for minimal matching + { + $first = $1; + $last = $2; + # Problem with two directly following listseparators. For example a path with two ";;" directly behind each other + $first =~ s/^$listseparator//; + push(@newarray, "$first\n"); + } + + push(@newarray, "$last\n"); + + return \@newarray; +} + +######################################################### +# Checking the local system +# Checking existence of needed files in include path +######################################################### + +sub check_system_path +{ + my $onefile; + my $error = 0; + my $pathvariable = $ENV{'PATH'}; + my $local_pathseparator = $pathseparator; + + if( $^O =~ /cygwin/i ) + { # When using cygwin's perl the PATH variable is POSIX style and ... + $pathvariable = qx{cygpath -mp "$pathvariable"} ; + # has to be converted to DOS style for further use. + $local_pathseparator = ';'; + } + my $patharrayref = convert_stringlist_into_array(\$pathvariable, $local_pathseparator); + + my @needed_files_in_path = ("expand.exe"); + if ( $localmsidbpath eq "" ) { push(@needed_files_in_path, "msidb.exe"); } # not found locally -> search in path + my @optional_files_in_path = ("msiinfo.exe"); + + print("\nChecking required files:\n"); + + foreach $onefile ( @needed_files_in_path ) + { + print("... searching $onefile ..."); + + my $fileref = get_sourcepath_from_filename_and_includepath(\$onefile, $patharrayref); + + if ( $$fileref eq "" ) + { + $error = 1; + print( "$onefile not found\n" ); + } + else + { + print( "\tFound: $$fileref\n" ); + } + } + + if ( $error ) { exit_program("ERROR: Could not find all needed files in path (using setsolar should help)!"); } + + print("\nChecking optional files:\n"); + + foreach $onefile ( @optional_files_in_path ) + { + print("... searching $onefile ..."); + + my $fileref = get_sourcepath_from_filename_and_includepath(\$onefile, $patharrayref); + + if ( $$fileref eq "" ) + { + print( "$onefile not found\n" ); + if ( $onefile eq "msiinfo.exe" ) { $msiinfo_available = 0; } + } + else + { + print( "\tFound: $$fileref\n" ); + if ( $onefile eq "msiinfo.exe" ) { $msiinfo_available = 1; } + } + } + +} + +########################################################################## +# Searching a file in a list of paths +########################################################################## + +sub get_sourcepath_from_filename_and_includepath +{ + my ($searchfilenameref, $includepatharrayref) = @_; + + my $onefile = ""; + my $foundsourcefile = 0; + + for ( my $j = 0; $j <= $#{$includepatharrayref}; $j++ ) + { + my $includepath = ${$includepatharrayref}[$j]; + $includepath =~ s/^\s*//; + $includepath =~ s/\s*$//; + + $onefile = $includepath . $separator . $$searchfilenameref; + + if ( -f $onefile ) + { + $foundsourcefile = 1; + last; + } + } + + if (!($foundsourcefile)) { $onefile = ""; } + + return \$onefile; +} + +######################################################## +# Finding all files with a specified file extension +# in a specified directory. +######################################################## + +sub find_file_with_file_extension +{ + my ($extension, $dir) = @_; + + my @allfiles = (); + my @sourcefiles = (); + + $dir =~ s/\Q$separator\E\s*$//; + + opendir(DIR, $dir); + @sourcefiles = readdir(DIR); + closedir(DIR); + + my $onefile; + + foreach $onefile (@sourcefiles) + { + if ((!($onefile eq ".")) && (!($onefile eq ".."))) + { + if ( $onefile =~ /^\s*(\S.*?)\.$extension\s*$/ ) + { + push(@allfiles, $onefile) + } + } + } + + return \@allfiles; +} + +############################################################## +# Creating a directory with all parent directories +############################################################## + +sub create_directories +{ + my ($directory) = @_; + + if ( ! try_to_create_directory($directory) ) + { + my $parentdir = $directory; + get_path_from_fullqualifiedname(\$parentdir); + create_directories($parentdir); # recursive + } + + create_directory($directory); # now it has to succeed +} + +############################################################## +# Creating one directory +############################################################## + +sub create_directory +{ + my ($directory) = @_; + + if ( ! -d $directory ) { mkdir($directory, 0775); } +} + +############################################################## +# Trying to create a directory, no error if this fails +############################################################## + +sub try_to_create_directory +{ + my ($directory) = @_; + + my $returnvalue = 1; + my $created_directory = 0; + + if (!(-d $directory)) + { + $returnvalue = mkdir($directory, 0775); + + if ($returnvalue) + { + $created_directory = 1; + + my $localcall = "chmod 775 $directory \>\/dev\/null 2\>\&1"; + system($localcall); + } + else + { + $created_directory = 0; + } + } + else + { + $created_directory = 1; + } + + return $created_directory; +} + +########################################### +# Getting path from full file name +########################################### + +sub get_path_from_fullqualifiedname +{ + my ($longfilenameref) = @_; + + if ( $$longfilenameref =~ /\Q$separator\E/ ) # Is there a separator in the path? Otherwise the path is empty. + { + if ( $$longfilenameref =~ /^\s*(\S.*\Q$separator\E)(\S.+\S?)/ ) + { + $$longfilenameref = $1; + } + } + else + { + $$longfilenameref = ""; # there is no path + } +} + +############################################################## +# Getting file name from full file name +############################################################## + +sub make_absolute_filename_to_relative_filename +{ + my ($longfilenameref) = @_; + + # Either '/' or '\'. + if ( $$longfilenameref =~ /^.*[\/\\](\S.+\S?)/ ) + { + $$longfilenameref = $1; + } +} + +############################################ +# Exiting the program with an error +# This function is used instead of "die" +############################################ + +sub exit_program +{ + my ($message) = @_; + + print "\n***************************************************************\n"; + print "$message\n"; + print "***************************************************************\n"; + remove_complete_directory($savetemppath, 1); + print "\n" . get_time_string(); + exit(-1); +} + +################################################################################# +# Unpacking cabinet files with expand +################################################################################# + +sub unpack_cabinet_file +{ + my ($cabfilename, $unpackdir) = @_; + + my $expandfile = "expand.exe"; # has to be in the PATH + + # expand.exe has to be located in the system directory. + # Cygwin has another tool expand.exe, that converts tabs to spaces. This cannot be used of course. + # But this wrong expand.exe is typically in the PATH before this expand.exe, to unpack + # cabinet files. + + if ( $^O =~ /cygwin/i ) + { + $expandfile = $ENV{'SYSTEMROOT'} . "/system32/expand.exe"; # Has to be located in the systemdirectory + $expandfile =~ s/\\/\//; + if ( ! -f $expandfile ) { exit_program("ERROR: Did not find file $expandfile in the Windows system folder!"); } + } + + my $expandlogfile = $unpackdir . $separator . "expand.log"; + + # exclude cabinet file + # my $systemcall = $cabarc . " -o X " . $mergemodulehash->{'cabinetfile'}; + + my $systemcall = ""; + if ( $^O =~ /cygwin/i ) { + my $localunpackdir = qx{cygpath -w "$unpackdir"}; + $localunpackdir =~ s/\\/\\\\/g; + + my $localcabfilename = qx{cygpath -w "$cabfilename"}; + $localcabfilename =~ s/\\/\\\\/g; + $localcabfilename =~ s/\s*$//g; + + $systemcall = $expandfile . " " . $localcabfilename . " -F:\* " . $localunpackdir . " \>\/dev\/null 2\>\&1"; + } + else + { + $systemcall = $expandfile . " " . $cabfilename . " -F:\* " . $unpackdir . " \> " . $expandlogfile; + } + + my $returnvalue = system($systemcall); + + if ($returnvalue) { exit_program("ERROR: Could not execute $systemcall !"); } +} + +################################################################################# +# Extracting tables from msi database +################################################################################# + +sub extract_tables_from_database +{ + my ($fullmsidatabasepath, $workdir, $tablelist) = @_; + + my $msidb = "msidb.exe"; # Has to be in the path + if ( $localmsidbpath ) { $msidb = $localmsidbpath; } + my $infoline = ""; + my $systemcall = ""; + my $returnvalue = ""; + + if ( $^O =~ /cygwin/i ) { + chomp( $fullmsidatabasepath = qx{cygpath -w "$fullmsidatabasepath"} ); + # msidb.exe really wants backslashes. (And double escaping because system() expands the string.) + $fullmsidatabasepath =~ s/\\/\\\\/g; + $workdir =~ s/\\/\\\\/g; + # and if there are still slashes, they also need to be double backslash + $fullmsidatabasepath =~ s/\//\\\\/g; + $workdir =~ s/\//\\\\/g; + } + + # Export of all tables by using "*" + + $systemcall = $msidb . " -d " . $fullmsidatabasepath . " -f " . $workdir . " -e $tablelist"; + print "\nAnalyzing msi database\n"; + $returnvalue = system($systemcall); + + if ($returnvalue) + { + $infoline = "ERROR: Could not execute $systemcall !\n"; + exit_program($infoline); + } +} + +######################################################## +# Check, if this installation set contains +# internal cabinet files included into the msi +# database. +######################################################## + +sub check_for_internal_cabfiles +{ + my ($cabfilehash) = @_; + + my $contains_internal_cabfiles = 0; + my %allcabfileshash = (); + + foreach my $filename ( keys %{$cabfilehash} ) + { + if ( $filename =~ /^\s*\#/ ) # starting with a hash + { + $contains_internal_cabfiles = 1; + # setting real filename without hash as key and name with hash as value + my $realfilename = $filename; + $realfilename =~ s/^\s*\#//; + $allcabfileshash{$realfilename} = $filename; + } + } + + return ( $contains_internal_cabfiles, \%allcabfileshash ); +} + +################################################################# +# Exclude all cab files from the msi database. +################################################################# + +sub extract_cabs_from_database +{ + my ($msidatabase, $allcabfiles) = @_; + + my $infoline = ""; + my $fullsuccess = 1; + my $msidb = "msidb.exe"; # Has to be in the path + if ( $localmsidbpath ) { $msidb = $localmsidbpath; } + + my @all_excluded_cabfiles = (); + + if( $^O =~ /cygwin/i ) + { + $msidatabase = qx{cygpath -w "$msidatabase"}; + $msidatabase =~ s/\\/\\\\/g; + $msidatabase =~ s/\s*$//g; + } + else + { + # msidb.exe really wants backslashes. (And double escaping because system() expands the string.) + $msidatabase =~ s/\//\\\\/g; + } + + foreach my $onefile ( keys %{$allcabfiles} ) + { + my $systemcall = $msidb . " -d " . $msidatabase . " -x " . $onefile; + system($systemcall); + push(@all_excluded_cabfiles, $onefile); + } + + \@all_excluded_cabfiles; +} + +################################################################################ +# Collect all DiskIds to the corresponding cabinet files from Media.idt. +################################################################################ + +sub analyze_media_file +{ + my ($filecontent) = @_; + + my %diskidhash = (); + + for ( my $i = 0; $i <= $#{$filecontent}; $i++ ) + { + if ( $i < 3 ) { next; } + + if ( ${$filecontent}[$i] =~ /^\s*(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\s*$/ ) + { + my $diskid = $1; + my $cabfile = $4; + + $diskidhash{$cabfile} = $diskid; + } + } + + return \%diskidhash; +} + +################################################################################ +# Analyzing the content of Directory.idt +################################################################################# + +sub analyze_directory_file +{ + my ($filecontent) = @_; + + my %table = (); + + for ( my $i = 0; $i <= $#{$filecontent}; $i++ ) + { + if (( $i == 0 ) || ( $i == 1 ) || ( $i == 2 )) { next; } + + if ( ${$filecontent}[$i] =~ /^\s*(.*?)\t(.*?)\t(.*?)\s*$/ ) + { + my $dir = $1; + my $parent = $2; + my $name = $3; + + if ( $name =~ /^\s*(.*?)\s*\:\s*(.*?)\s*$/ ) { $name = $2; } + if ( $name =~ /^\s*(.*?)\s*\|\s*(.*?)\s*$/ ) { $name = $2; } + + my %helphash = (); + $helphash{'Directory_Parent'} = $parent; + $helphash{'DefaultDir'} = $name; + $table{$dir} = \%helphash; + } + } + + return \%table; +} + +################################################################################# +# Analyzing the content of Component.idt +################################################################################# + +sub analyze_component_file +{ + my ($filecontent) = @_; + + my %table = (); + + for ( my $i = 0; $i <= $#{$filecontent}; $i++ ) + { + if (( $i == 0 ) || ( $i == 1 ) || ( $i == 2 )) { next; } + + if ( ${$filecontent}[$i] =~ /^\s*(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\s*$/ ) + { + my $component = $1; + my $dir = $3; + + $table{$component} = $dir; + } + } + + return \%table; +} + +################################################################################# +# Analyzing the content of File.idt +################################################################################# + +sub analyze_file_file +{ + my ($filecontent) = @_; + + my %table = (); + my %fileorder = (); + my $maxsequence = 0; + + for ( my $i = 0; $i <= $#{$filecontent}; $i++ ) + { + if (( $i == 0 ) || ( $i == 1 ) || ( $i == 2 )) { next; } + + if ( ${$filecontent}[$i] =~ /^\s*(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\s*$/ ) + { + my $file = $1; + my $comp = $2; + my $filename = $3; + my $sequence = $8; + + if ( $filename =~ /^\s*(.*?)\s*\|\s*(.*?)\s*$/ ) { $filename = $2; } + + my %helphash = (); + $helphash{'Component'} = $comp; + $helphash{'FileName'} = $filename; + $helphash{'Sequence'} = $sequence; + + $table{$file} = \%helphash; + + $fileorder{$sequence} = $file; + + if ( $sequence > $maxsequence ) { $maxsequence = $sequence; } + } + } + + return (\%table, \%fileorder, $maxsequence); +} + +#################################################################################### +# Recursively creating the directory tree +#################################################################################### + +sub create_directory_tree +{ + my ($parent, $pathcollector, $fulldir, $dirhash) = @_; + + foreach my $dir ( keys %{$dirhash} ) + { + if (( $dirhash->{$dir}->{'Directory_Parent'} eq $parent ) && ( $dirhash->{$dir}->{'DefaultDir'} ne "." )) + { + my $dirname = $dirhash->{$dir}->{'DefaultDir'}; + # Create the directory + my $newdir = $fulldir . $separator . $dirname; + if ( ! -f $newdir ) { mkdir $newdir; } + # Saving in collector + $pathcollector->{$dir} = $newdir; + # Iteration + create_directory_tree($dir, $pathcollector, $newdir, $dirhash); + } + } +} + +#################################################################################### +# Creating the directory tree +#################################################################################### + +sub create_directory_structure +{ + my ($dirhash, $targetdir) = @_; + + print "Creating directories\n"; + + my %fullpathhash = (); + + my @startparents = ("TARGETDIR", "INSTALLLOCATION"); + + foreach $dir (@startparents) { create_directory_tree($dir, \%fullpathhash, $targetdir, $dirhash); } + + # Also adding the paths of the startparents + foreach $dir (@startparents) + { + if ( ! exists($fullpathhash{$dir}) ) { $fullpathhash{$dir} = $targetdir; } + } + + return \%fullpathhash; +} + +#################################################################################### +# Cygwin: Setting privileges for files +#################################################################################### + +sub change_privileges +{ + my ($destfile, $privileges) = @_; + + my $localcall = "chmod $privileges " . "\"" . $destfile . "\""; + system($localcall); +} + +#################################################################################### +# Cygwin: Setting privileges for files recursively +#################################################################################### + +sub change_privileges_full +{ + my ($target) = @_; + + print "Changing privileges\n"; + + my $localcall = "chmod -R 755 " . "\"" . $target . "\""; + system($localcall); +} + +###################################################### +# Creating a new directory with defined privileges +###################################################### + +sub create_directory_with_privileges +{ + my ($directory, $privileges) = @_; + + my $returnvalue = 1; + my $infoline = ""; + + if (!(-d $directory)) + { + my $localprivileges = oct("0".$privileges); # changes "777" to 0777 + $returnvalue = mkdir($directory, $localprivileges); + + if ($returnvalue) + { + my $localcall = "chmod $privileges $directory \>\/dev\/null 2\>\&1"; + system($localcall); + } + } + else + { + my $localcall = "chmod $privileges $directory \>\/dev\/null 2\>\&1"; + system($localcall); + } +} + +###################################################### +# Creating a unique directory with pid extension +###################################################### + +sub create_pid_directory +{ + my ($directory) = @_; + + $directory =~ s/\Q$separator\E\s*$//; + my $pid = $$; # process id + my $time = time(); # time + + $directory = $directory . "_" . $pid . $time; + + if ( ! -d $directory ) { create_directory($directory); } + else { exit_program("ERROR: Directory $directory already exists!"); } + + return $directory; +} + +#################################################################################### +# Copying files into installation set +#################################################################################### + +sub copy_files_into_directory_structure +{ + my ($fileorder, $filehash, $componenthash, $fullpathhash, $maxsequence, $unpackdir, $installdir, $dirhash) = @_; + + print "Copying files\n"; + + for ( my $i = 1; $i <= $maxsequence; $i++ ) + { + if ( exists($fileorder->{$i}) ) + { + my $file = $fileorder->{$i}; + if ( ! exists($filehash->{$file}->{'Component'}) ) { exit_program("ERROR: Did not find component for file: \"$file\"."); } + my $component = $filehash->{$file}->{'Component'}; + if ( ! exists($componenthash->{$component}) ) { exit_program("ERROR: Did not find directory for component: \"$component\"."); } + my $dirname = $componenthash->{$component}; + if ( ! exists($fullpathhash->{$dirname}) ) { exit_program("ERROR: Did not find full directory path for dir: \"$dirname\"."); } + my $destdir = $fullpathhash->{$dirname}; + if ( ! exists($filehash->{$file}->{'FileName'}) ) { exit_program("ERROR: Did not find \"FileName\" for file: \"$file\"."); } + my $destfile = $filehash->{$file}->{'FileName'}; + + $destfile = $destdir . $separator . $destfile; + my $sourcefile = $unpackdir . $separator . $file; + + if ( ! -f $sourcefile ) + { + # It is possible, that this was an unpacked file + # Looking in the dirhash, to find the subdirectory in the installation set (the id is $dirname) + # subdir is not recursively analyzed, only one directory. + + my $oldsourcefile = $sourcefile; + my $subdir = ""; + if ( exists($dirhash->{$dirname}->{'DefaultDir'}) ) { $subdir = $dirhash->{$dirname}->{'DefaultDir'} . $separator; } + my $realfilename = $filehash->{$file}->{'FileName'}; + my $localinstalldir = $installdir; + + $localinstalldir =~ s/\\\s*$//; + $localinstalldir =~ s/\/\s*$//; + + $sourcefile = $localinstalldir . $separator . $subdir . $realfilename; + + if ( ! -f $sourcefile ) { exit_program("ERROR: File not found: \"$oldsourcefile\" (or \"$sourcefile\")."); } + } + + my $copyreturn = copy($sourcefile, $destfile); + + if ( ! $copyreturn) { exit_program("ERROR: Could not copy $source to $dest\n"); } + + # if (( $^O =~ /cygwin/i ) && ( $destfile =~ /\.exe\s*$/ )) { change_privileges($destfile, "775"); } + } + # else # allowing missing sequence numbers ? + # { + # exit_program("ERROR: No file assigned to sequence $i"); + # } + } +} + +###################################################### +# Removing a complete directory with subdirectories +###################################################### + +sub remove_complete_directory +{ + my ($directory, $start) = @_; + + my @content = (); + my $infoline = ""; + + $directory =~ s/\Q$separator\E\s*$//; + + if ( -d $directory ) + { + if ( $start ) { print "Removing directory $directory\n"; } + + opendir(DIR, $directory); + @content = readdir(DIR); + closedir(DIR); + + my $oneitem; + + foreach $oneitem (@content) + { + if ((!($oneitem eq ".")) && (!($oneitem eq ".."))) + { + my $item = $directory . $separator . $oneitem; + + if ( -f $item || -l $item ) # deleting files or links + { + unlink($item); + } + + if ( -d $item ) # recursive + { + remove_complete_directory($item, 0); + } + } + } + + # try to remove empty directory + my $returnvalue = rmdir $directory; + if ( ! $returnvalue ) { print "Warning: Problem with removing empty dir $directory\n"; } + } +} + +#################################################################################### +# Defining a temporary path +#################################################################################### + +sub get_temppath +{ + my $temppath = ""; + + if (( $ENV{'TMP'} ) || ( $ENV{'TEMP'} )) + { + if ( $ENV{'TMP'} ) { $temppath = $ENV{'TMP'}; } + elsif ( $ENV{'TEMP'} ) { $temppath = $ENV{'TEMP'}; } + + $temppath =~ s/\Q$separator\E\s*$//; # removing ending slashes and backslashes + $temppath = $temppath . $separator . $globaltempdirname; + $temppath = mkdtemp($temppath); + + my $dirsave = $temppath; + + $temppath = $temppath . $separator . "a"; + $temppath = create_pid_directory($temppath); + + if ( ! -d $temppath ) { exit_program("ERROR: Failed to create directory $temppath ! Possible reason: Wrong privileges in directory $dirsave."); } + + if ( $^O =~ /cygwin/i ) + { + $temppath =~ s/\\/\\\\/g; + chomp( $temppath = qx{cygpath -w "$temppath"} ); + } + + $savetemppath = $temppath; + } + else + { + exit_program("ERROR: Could not set temporary directory (TMP and TEMP not set!)."); + } + + return $temppath; +} + +#################################################################################### +# Reading one file +#################################################################################### + +sub read_file +{ + my ($localfile) = @_; + + my @localfile = (); + + open( IN, "<$localfile" ) || exit_program("ERROR: Cannot open file $localfile for reading"); + + # Don't use "my @localfile = <IN>" here, because + # perl has a problem with the internal "large_and_huge_malloc" function + # when calling perl using MacOS 10.5 with a perl built with MacOS 10.4 + while ( $line = <IN> ) { + push @localfile, $line; + } + + close( IN ); + + return \@localfile; +} + +############################################################### +# Setting the time string for the +# Summary Information stream in the +# msi database of the admin installations. +############################################################### + +sub get_sis_time_string +{ + # Syntax: <yyyy/mm/dd hh:mm:ss> + my $second = (localtime())[0]; + my $minute = (localtime())[1]; + my $hour = (localtime())[2]; + my $day = (localtime())[3]; + my $month = (localtime())[4]; + my $year = 1900 + (localtime())[5]; + $month++; + + if ( $second < 10 ) { $second = "0" . $second; } + if ( $minute < 10 ) { $minute = "0" . $minute; } + if ( $hour < 10 ) { $hour = "0" . $hour; } + if ( $day < 10 ) { $day = "0" . $day; } + if ( $month < 10 ) { $month = "0" . $month; } + + my $timestring = $year . "/" . $month . "/" . $day . " " . $hour . ":" . $minute . ":" . $second; + + return $timestring; +} + +############################################################### +# Writing content of administrative installations into +# Summary Information Stream of msi database. +# This is required for example for following +# patch processes using Windows Installer service. +############################################################### + +sub write_sis_info +{ + my ($msidatabase) = @_; + + print "Setting SIS in msi database\n"; + + if ( ! -f $msidatabase ) { exit_program("ERROR: Cannot find file $msidatabase"); } + + my $msiinfo = "msiinfo.exe"; # Has to be in the path + my $infoline = ""; + my $systemcall = ""; + my $returnvalue = ""; + + # Required setting for administrative installations: + # -w 4 (source files are unpacked), wordcount + # -s <date of admin installation>, LastPrinted, Syntax: <yyyy/mm/dd hh:mm:ss> + # -l <person_making_admin_installation>, LastSavedBy + + my $wordcount = 4; # Unpacked files + my $lastprinted = get_sis_time_string(); + my $lastsavedby = "Installer"; + + my $localmsidatabase = $msidatabase; + + if( $^O =~ /cygwin/i ) + { + $localmsidatabase = qx{cygpath -w "$localmsidatabase"}; + $localmsidatabase =~ s/\\/\\\\/g; + $localmsidatabase =~ s/\s*$//g; + } + + $systemcall = $msiinfo . " " . "\"" . $localmsidatabase . "\"" . " -w " . $wordcount . " -s " . "\"" . $lastprinted . "\"" . " -l $lastsavedby"; + + $returnvalue = system($systemcall); + + if ($returnvalue) + { + $infoline = "ERROR: Could not execute $systemcall !\n"; + exit_program($infoline); + } +} + +############################################################### +# Convert time string +############################################################### + +sub convert_timestring +{ + my ($secondstring) = @_; + + my $timestring = ""; + + if ( $secondstring < 60 ) # less than a minute + { + if ( $secondstring < 10 ) { $secondstring = "0" . $secondstring; } + $timestring = "00\:$secondstring min\."; + } + elsif ( $secondstring < 3600 ) + { + my $minutes = $secondstring / 60; + my $seconds = $secondstring % 60; + if ( $minutes =~ /(\d*)\.\d*/ ) { $minutes = $1; } + if ( $minutes < 10 ) { $minutes = "0" . $minutes; } + if ( $seconds < 10 ) { $seconds = "0" . $seconds; } + $timestring = "$minutes\:$seconds min\."; + } + else # more than one hour + { + my $hours = $secondstring / 3600; + my $secondstring = $secondstring % 3600; + my $minutes = $secondstring / 60; + my $seconds = $secondstring % 60; + if ( $hours =~ /(\d*)\.\d*/ ) { $hours = $1; } + if ( $minutes =~ /(\d*)\.\d*/ ) { $minutes = $1; } + if ( $hours < 10 ) { $hours = "0" . $hours; } + if ( $minutes < 10 ) { $minutes = "0" . $minutes; } + if ( $seconds < 10 ) { $seconds = "0" . $seconds; } + $timestring = "$hours\:$minutes\:$seconds hours"; + } + + return $timestring; +} + +############################################################### +# Returning time string for logging +############################################################### + +sub get_time_string +{ + my $currenttime = time(); + $currenttime = $currenttime - $starttime; + $currenttime = convert_timestring($currenttime); + $currenttime = localtime() . " \(" . $currenttime . "\)\n"; + return $currenttime; +} + +#################################################################################### +# Simulating an administrative installation +#################################################################################### + +$starttime = time(); + +getparameter(); +controlparameter(); +check_local_msidb(); +check_system_path(); +my $temppath = get_temppath(); + +print("\nmsi database: $databasepath\n"); +print("Destination directory: $targetdir\n" ); + +my $helperdir = $temppath . $separator . "installhelper"; +create_directory($helperdir); + +# Get File.idt, Component.idt and Directory.idt from database + +my $tablelist = "File Directory Component Media CustomAction"; +extract_tables_from_database($databasepath, $helperdir, $tablelist); + +# Set unpackdir +my $unpackdir = $helperdir . $separator . "unpack"; +create_directory($unpackdir); + +# Reading media table to check for internal cabinet files +my $filename = $helperdir . $separator . "Media.idt"; +if ( ! -f $filename ) { exit_program("ERROR: Could not find required file: $filename !"); } +my $filecontent = read_file($filename); +my $cabfilehash = analyze_media_file($filecontent); + +# Check, if there are internal cab files +my ( $contains_internal_cabfiles, $all_internal_cab_files) = check_for_internal_cabfiles($cabfilehash); + +if ( $contains_internal_cabfiles ) +{ + # Set unpackdir + my $cabdir = $helperdir . $separator . "internal_cabs"; + create_directory($cabdir); + my $from = cwd(); + chdir($cabdir); + # Exclude all cabinet files from database + my $all_excluded_cabs = extract_cabs_from_database($databasepath, $all_internal_cab_files); + print "Unpacking files from internal cabinet file(s)\n"; + foreach my $cabfile ( @{$all_excluded_cabs} ) { unpack_cabinet_file($cabfile, $unpackdir); } + chdir($from); +} + +# Unpack all cab files into $helperdir, cab files must be located next to msi database +my $installdir = $databasepath; + +get_path_from_fullqualifiedname(\$installdir); + +my $databasefilename = $databasepath; +make_absolute_filename_to_relative_filename(\$databasefilename); + +my $cabfiles = find_file_with_file_extension("cab", $installdir); + +if (( $#{$cabfiles} < 0 ) && ( ! $contains_internal_cabfiles )) { exit_program("ERROR: Did not find any cab file in directory $installdir"); } + +print "Unpacking files from cabinet file(s)\n"; +for ( my $i = 0; $i <= $#{$cabfiles}; $i++ ) +{ + my $cabfile = $installdir . $separator . ${$cabfiles}[$i]; + unpack_cabinet_file($cabfile, $unpackdir); +} + +# Reading tables +$filename = $helperdir . $separator . "Directory.idt"; +$filecontent = read_file($filename); +my $dirhash = analyze_directory_file($filecontent); + +$filename = $helperdir . $separator . "Component.idt"; +$filecontent = read_file($filename); +my $componenthash = analyze_component_file($filecontent); + +$filename = $helperdir . $separator . "File.idt"; +$filecontent = read_file($filename); +my ( $filehash, $fileorder, $maxsequence ) = analyze_file_file($filecontent); + +# Creating the directory structure +my $fullpathhash = create_directory_structure($dirhash, $targetdir); + +# Copying files +copy_files_into_directory_structure($fileorder, $filehash, $componenthash, $fullpathhash, $maxsequence, $unpackdir, $installdir, $dirhash); +if ( $^O =~ /cygwin/i ) { change_privileges_full($targetdir); } + +my $msidatabase = $targetdir . $separator . $databasefilename; +my $copyreturn = copy($databasepath, $msidatabase); +if ( ! $copyreturn) { exit_program("ERROR: Could not copy $source to $dest\n"); } + +# Saving info in Summary Information Stream of msi database (required for following patches) +if ( $msiinfo_available ) { write_sis_info($msidatabase); } + +# Removing the helper directory +remove_complete_directory($temppath, 1); + +print "\nSuccessful installation: " . get_time_string(); diff --git a/setup_native/scripts/fake-db.spec b/setup_native/scripts/fake-db.spec new file mode 100644 index 000000000..a7a5c318b --- /dev/null +++ b/setup_native/scripts/fake-db.spec @@ -0,0 +1,57 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + +Name: fake-db +Version: 1.0 +Release: 0 +Summary: This is a dummy package +Group: dummy +License: LGPLv3 with MPLv2 on ALv2 +BuildArch: noarch +AutoReqProv: no +%define _tmppath /tmp +#BuildRoot: %{_tmppath}/%{name}-root +Provides: libgnomevfs-2.so.0 +Provides: libgnomevfs-2.so.0()(64bit) +Provides: libfreetype.so.6 +Provides: libfreetype.so.6()(64bit) +Provides: /bin/sh +Provides: /bin/basename +Provides: /bin/cat +Provides: /bin/cp +Provides: /bin/gawk +Provides: /bin/grep +Provides: /bin/ln +Provides: /bin/ls +Provides: /bin/mkdir +Provides: /bin/mv +Provides: /bin/pwd +Provides: /bin/rm +Provides: /bin/sed +Provides: /bin/sort +Provides: /bin/touch +Provides: /usr/bin/cut +Provides: /usr/bin/dirname +Provides: /usr/bin/expr +Provides: /usr/bin/find +Provides: /usr/bin/tail +Provides: /usr/bin/tr +Provides: /usr/bin/wc +%description +a dummy package +%files diff --git a/setup_native/scripts/install_create.pl b/setup_native/scripts/install_create.pl new file mode 100644 index 000000000..c7659c40e --- /dev/null +++ b/setup_native/scripts/install_create.pl @@ -0,0 +1,60 @@ +: # -*- perl -*- +eval 'exec perl -wS $0 ${1+"$@"}' + if 0; +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# +# create setup self extracting script + +if( $#ARGV < 2 ) + { + print <<ENDHELP; +USAGE: $0 <inputshellscript> <libraryfile> <outputshellscript> + <inputshellscript>: the start shell script, located next to this perl script + <libraryfile>: the library file, that is included into the shell script + <outfile>: the target shellscript + +ENDHELP + exit; + } + +$infile = $ARGV[0]; +$library = $ARGV[1]; +$outfile = $ARGV[2]; + +# read script header +open( SCRIPT, "<$infile" ) || die "cannot open $infile"; +open( OUTFILE, ">$outfile$$.tmp" ) || die "cannot open $outfile"; +@scriptlines = <SCRIPT>; +$linenum = $#scriptlines+2; +foreach (@scriptlines) +{ + # lineend conversion (be on the safe side) + chomp; + $_ =~ tr/\r//; + s/^\s*linenum=.*$/linenum=$linenum/; + print OUTFILE "$_\n"; +} +close( SCRIPT ); +close( OUTFILE ); + +system( "cat $library >>$outfile$$.tmp" ); +rename "$outfile$$.tmp", "$outfile"; + +chmod 0775, $outfile; + +exit; diff --git a/setup_native/scripts/install_linux.sh b/setup_native/scripts/install_linux.sh new file mode 100644 index 000000000..abf9b2d84 --- /dev/null +++ b/setup_native/scripts/install_linux.sh @@ -0,0 +1,311 @@ +#!/usr/bin/env bash +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + +ADD="no" +LINK="no" +UPDATE="ask" +UNPACKDIR="" +USAGE="Usage: $0 [-a,--add] [-l,--link] [-U,--update] [-h,--help] <rpm-source-dir> <office-installation-dir>" + +help() +{ + echo + echo "User Mode Installation script for developer and knowledgeable early access tester" + echo + echo "This installation method is not intended for use in a production environment!" + echo "Using this script is unsupported and completely at your own risk" + echo + echo "Usage:" $0 [-lU] "<rpm-source-dir> <office-installation-dir>" + echo " <rpm-source-dir>: directory *only* containing the Linux rpm packages to be installed" + echo " or language pack shell script containing the rpm packages" + echo " <office-installation-dir>: directory to where the office will get installed into" + echo + echo "Optional Parameter:" + echo " -a,--add: add to an existing <office-installation-dir>" + echo " -l,--link: create a link \"soffice\" in $HOME" + echo " -U,--update: update without asking" + echo " -h,--help: output this help" + echo +} + +try_to_unpack_languagepack_file() +{ + FILENAME=$PACKAGE_PATH + + # Checking, if $FILENAME is a language pack. + # String "language package" has to exist in the shell script file. + # If this is no language pack, the installation is not supported + + SEARCHSTRING=`head --lines=10 $FILENAME | grep "language package"` + + if [ ! -z "$SEARCHSTRING" ] + then + echo "First parameter $FILENAME is a language pack"; + else + printf "\nERROR: First parameter $FILENAME is a file, but no language pack shell script.\n" + echo $USAGE + exit 2 + fi + + echo "Unpacking shell script $FILENAME" + TAILLINE=`head --lines=20 $FILENAME | sed --quiet 's/linenum=//p'` + + UNPACKDIR=`mktemp -d -p /var/tmp` + tail -n +$TAILLINE $FILENAME | gunzip | (cd $UNPACKDIR; tar xvf -) + + # Setting the new package path, in which the packages exist + PACKAGE_PATH=$UNPACKDIR + + # Setting variable UPDATE, because an Office installation has to exist, if a language pack shall be installed + UPDATE="yes" +} + +# +# this script is for userland not for root +# + +if [ $UID -eq 0 ] +then + printf "\nThis script is for installation without administrative rights only\nPlease use rpm to install as root\n" + help + exit 2 +fi + +set -- `getopt -u -o 'alhU' -l 'add,link,help,update' -- $*` + +if [ $? != 0 ] +then + echo $USAGE + exit 2 +fi + +for i in $* +do + case $i in + -a|--add) ADD="yes"; shift;; + -h|--help) help; exit 0;; + -l|--link) LINK="yes"; shift;; + -U|--update) UPDATE="yes"; shift;; + --) shift; break;; + esac +done + +if [ $# != 2 ] +then + echo $USAGE + echo "Example: $0 . ~/libreoffice" + exit 2 +fi + +PACKAGE_PATH=$1 + +# +# If the first parameter is a shell script (download installation set), the packages have to +# be unpacked into temp directory +# + +if [ -f "$PACKAGE_PATH" ] +then + try_to_unpack_languagepack_file +fi + +# +# Check and get the list of packages to install +# + +RPMLIST=`find $PACKAGE_PATH -maxdepth 2 -type f -name "*.rpm" ! -name "*-menus-*" ! -name "*-desktop-integration-*" ! -name "jre*" ! -name "*-userland-*" -print` + +if [ -z "$RPMLIST" ] +then + printf "\n$0: No packages found in $PACKAGE_PATH\n" + exit 2 +fi + +# #163256# check if we are on a debian system... +if rpm --help | grep debian >/dev/null; +then + DEBIAN_FLAGS="--force-debian --nodeps" +else + DEBIAN_FLAGS= +fi + +# +# Determine whether this should be an update or a fresh install +# + +INSTALLDIR=$2 +RPM_DB_PATH=${INSTALLDIR}/.RPM_OFFICE_DATABASE + +# Check for versionrc +if [ -f ${INSTALLDIR}/program/versionrc ]; then VERSIONRC=versionrc; fi + +if [ "$UPDATE" = "ask" ] +then + PRODUCT=`sed --silent -e " +/^buildid=/ { +s/buildid=\(.*\)/ [\1]/ +h +} +/^ProductKey=/ { +s/ProductKey=// +G +p +}" ${INSTALLDIR}/program/${VERSIONRC:-bootstraprc} 2>/dev/null | tr -d "\012"` + + if [ ! -z "$PRODUCT" ] + then + echo + echo "Found an installation of $PRODUCT in $INSTALLDIR" + echo + while [ "$UPDATE" != "yes" ] + do + read -a UPDATE -p "Do you want to update this installation (yes/no)? " + if [ "$UPDATE" = "no" ] + then + exit 2 + fi + done + elif [ -d $RPM_DB_PATH -a "$ADD" = "no" ] + then + echo + echo "The following packages are already installed in $INSTALLDIR" + echo + rpm --dbpath `cd $RPM_DB_PATH; pwd` --query --all + echo + while [ "$UPDATE" != "yes" ] + do + read -a UPDATE -p "Do you want to continue with this installation (yes/no)? " + if [ "$UPDATE" = "no" ] + then + exit 2 + fi + done + else + UPDATE="no" + fi +fi + +# +# Check/Create installation directory +# + +if [ "$UPDATE" = "yes" ] +then + # restore original bootstraprc + mv -f ${INSTALLDIR}/program/bootstraprc.orig ${INSTALLDIR}/program/bootstraprc 2>/dev/null + + # the RPM_DB_PATH must be absolute + if [ ! "${RPM_DB_PATH:0:1}" = "/" ]; then + RPM_DB_PATH=`cd ${RPM_DB_PATH}; pwd` + fi + + # we should use --freshen for updates to not add languages with patches, but this will break + # language packs, so leave it for now .. +# RPMCMD="--freshen" + RPMCMD="--upgrade" +else + rmdir ${INSTALLDIR} 2>/dev/null + + mkdir -p $RPM_DB_PATH || exit 2 + # XXX why? XXX + chmod 700 $RPM_DB_PATH + + # the RPM_DB_PATH must be absolute + if [ ! "${RPM_DB_PATH:0:1}" = "/" ]; then + RPM_DB_PATH=`cd ${RPM_DB_PATH}; pwd` + fi + + # Creating RPM database and initializing + if [ "$ADD" = "no" ]; then + rpm --initdb --dbpath $RPM_DB_PATH + fi + + # Default install command + RPMCMD="--install" +fi + +# populate the private rpm database with the dependencies needed +FAKEDBRPM=`mktemp -p /tmp fake-db-1.0-XXXXXXXXXX.noarch.rpm` +linenum=??? +tail -n +$linenum $0 > $FAKEDBRPM + +rpm ${DEBIAN_FLAGS} --upgrade --ignoresize --dbpath $RPM_DB_PATH $FAKEDBRPM + +rm -f $FAKEDBRPM + +echo "Packages found:" +for i in $RPMLIST ; do + echo `basename $i` +done + +# +# Perform the installation +# + +echo +echo "####################################################################" +echo "# Installation of the found packages #" +echo "####################################################################" +echo +echo "Path to the database: " $RPM_DB_PATH +echo "Path to the packages: " $PACKAGE_PATH +echo "Path to the installation: " $INSTALLDIR +echo +echo "Installing the RPMs" + +ABSROOT=`cd ${INSTALLDIR}; pwd` +RELOCATIONS=`rpm -qp --qf "--relocate %{PREFIXES}=${ABSROOT}%{PREFIXES} \n" $RPMLIST | sort -u | tr -d "\012"` +UserInstallation=\$BRAND_BASE_DIR/../UserInstallation rpm ${DEBIAN_FLAGS} --nodeps $RPMCMD --ignoresize -vh $RELOCATIONS --dbpath $RPM_DB_PATH $RPMLIST + +# +# Create a link into the users home directory +# + +if [ "$LINK" = "yes" ] +then + find `cd "$INSTALLDIR" && pwd` -name soffice -type f -perm /u+x -exec /bin/bash -ce 'ln -sf "$0" "$HOME/soffice" && echo "Creating link from $0 to $HOME/soffice"' {} \; +fi + +if [ "$UPDATE" = "yes" -a ! -f $INSTALLDIR/program/bootstraprc ] +then + echo + echo "Update failed due to a bug in RPM, uninstalling .." + rpm ${DEBIAN_FLAGS} --erase -v --nodeps --dbpath $RPM_DB_PATH `rpm --query --queryformat "%{NAME} " --package $RPMLIST --dbpath $RPM_DB_PATH` + echo + echo "Now re-installing new packages .." + echo + rpm ${DEBIAN_FLAGS} --install --nodeps --ignoresize -vh $RELOCATIONS --dbpath $RPM_DB_PATH $RPMLIST + echo +fi + +# patch the "bootstraprc" to create a self-containing installation +find "$INSTALLDIR" -type f -name bootstraprc -exec /bin/bash -ce 'test ! -e "$0".orig && mv "$0" "$0".orig && sed '\''s,^UserInstallation=$SYSUSERCONFIG.*,UserInstallation=$BRAND_BASE_DIR/../UserInstallation,'\'' "$0".orig > "$0"' {} \; + +# if an unpack directory exists, it can be removed now +if [ ! -z "$UNPACKDIR" ] +then + rm $UNPACKDIR/*.rpm + rmdir $UNPACKDIR + echo "Removed temporary directory $UNPACKDIR" +fi + +echo +echo "Installation done ..." + +exit 0 diff --git a/setup_native/scripts/langpackscript.sh b/setup_native/scripts/langpackscript.sh new file mode 100644 index 000000000..1a6bb39a3 --- /dev/null +++ b/setup_native/scripts/langpackscript.sh @@ -0,0 +1,169 @@ +#!/bin/sh +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + +MYUID=`id | sed "s/(.*//g" | sed "s/.*=//"` + +if [ $MYUID -ne 0 ] +then + echo You need to have super-user rights to install this language package + exit 1 +fi + +linenum=LINENUMBERPLACEHOLDER + +# Determining current platform + +platform=`uname -s` + +case $platform in +SunOS) + tail_prog="tail" + ;; +Linux) + tail_prog="tail -n" + ;; +*) + tail_prog="tail" + ;; +esac + +more << "EOF" +LICENSEFILEPLACEHOLDER +EOF + +agreed= +while [ x$agreed = x ]; do + echo + echo "Do you agree to the above license terms? [yes or no] " + read reply leftover + case $reply in + y* | Y*) + agreed=1;; + n* | N*) + echo "If you don't agree to the license you can't install this software"; + exit 1;; + esac +done + +case $platform in +SunOS) + SEARCHPACKAGENAME="BASISPACKAGEPREFIXPLACEHOLDERPRODUCTVERSIONPLACEHOLDER-core01" + echo + echo "Searching for the FULLPRODUCTNAMELONGPLACEHOLDER installation ..." + PACKAGENAME=`pkginfo -x | grep $SEARCHPACKAGENAME | sed "s/ .*//"` + if [ "x$PACKAGENAME" != "x" ] + then + PRODUCTINSTALLLOCATION="`pkginfo -r $PACKAGENAME`" + else + echo "FULLPRODUCTNAMELONGPLACEHOLDER not installed (no package $SEARCHPACKAGENAME installed)" + exit 1 + fi + ;; +Linux) + SEARCHPACKAGENAME="BASISPACKAGEPREFIXPLACEHOLDERPRODUCTVERSIONPLACEHOLDER-core01" + FIXPATH="/openoffice.org" + echo + echo "Searching for the FULLPRODUCTNAMELONGPLACEHOLDER installation ..." + RPMNAME=`rpm -qa | grep $SEARCHPACKAGENAME` + if [ "x$RPMNAME" != "x" ] + then + PRODUCTINSTALLLOCATION="`rpm -ql $RPMNAME | head -n 1`" + else + echo "FULLPRODUCTNAMELONGPLACEHOLDER not installed (no package $SEARCHPACKAGENAME installed)" + exit 1 + fi + PRODUCTINSTALLLOCATION=`echo $PRODUCTINSTALLLOCATION | sed "s#${FIXPATH}##"` + ;; +*) + echo "Unsupported platform" + exit 1 + ;; +esac + +# Asking for the installation directory + +# echo +# echo "Where do you want to install the language pack ? [$PRODUCTINSTALLLOCATION] " +# read reply leftover +# if [ "x$reply" != "x" ] +# then +# PRODUCTINSTALLLOCATION="$reply" +# fi + +# Unpacking + +outdir=`mktemp -d -p /var/tmp` + +#diskSpace=`df -k $outdir | $tail_prog -1 | awk '{if ( $4 ~ /%/) { print $3 } else { print $4 } }'` +#if [ $diskSpace -lt $diskSpaceRequired ]; then +# printf "You will need at least %s kBytes of free disk space\n" $diskSpaceRequired +# printf "Please free up the required disk space and try again\n" +# exit 3 +#fi + +trap 'rm -rf $outdir; exit 1' HUP INT QUIT TERM +echo "Unpacking and installing..." + +#if [ -x /usr/bin/sum ] ; then +# echo "Checksumming..." +# +# sum=`/usr/bin/sum $outdir/$outname` +# index=1 +# for s in $sum +# do +# case $index in +# 1) sum1=$s; +# index=2; +# ;; +# 2) sum2=$s; +# index=3; +# ;; +# esac +# done +# if expr $sum1 != <sum1replace> || expr $sum2 != <sum2replace> ; then +# echo "The download file appears to be corrupted. Please refer" +# echo "to the Troubleshooting section of the Installation" +# exit 1 +# fi +#else +# echo "Can't find /usr/bin/sum to do checksum. Continuing anyway." +#fi + +case $platform in +SunOS) + $tail_prog +$linenum $0 | gunzip | (cd $outdir; tar xvf -) + adminfile=$outdir/admin.$$ + echo "basedir=$PRODUCTINSTALLLOCATION" > $adminfile +INSTALLLINES + ;; +Linux) + $tail_prog +$linenum $0 | gunzip | (cd $outdir; tar xvf -) +INSTALLLINES + ;; +*) + echo "Unsupported platform" + exit 1 + ;; +esac + +rm -rf $outdir + +echo "Done..." + +exit 0 diff --git a/setup_native/scripts/mac_install.script b/setup_native/scripts/mac_install.script new file mode 100644 index 000000000..b81cca764 --- /dev/null +++ b/setup_native/scripts/mac_install.script @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + +# shell script as a workaround since it is hard to impossible to store compiled +# applescript in CVS and running osacompile would require a GUI session while +# building (or root privileges) +# using osascript only works when the shell script is camouflaged as application + +MY_DIR=$(dirname "$0") + +osascript "$MY_DIR/Resources/osx_install.applescript" diff --git a/setup_native/scripts/osx_install_languagepack.applescript b/setup_native/scripts/osx_install_languagepack.applescript new file mode 100644 index 000000000..4083b01cd --- /dev/null +++ b/setup_native/scripts/osx_install_languagepack.applescript @@ -0,0 +1,174 @@ +(* + + This file is part of the LibreOffice project. + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + + This file incorporates work covered by the following license notice: + + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright + ownership. The ASF licenses this file to you under the Apache + License, Version 2.0 (the "License"); you may not use this file + except in compliance with the License. You may obtain a copy of + the License at http://www.apache.org/licenses/LICENSE-2.0 . + +This script is meant to + 1) Identify installed instances of the product + 2) check whether the user has write-access (and if not + ask for authentication) + 3) install the shipped tarball +*) + +-- strings for localisations - to be meant to be replaced +-- by a makefile or similar +set OKLabel to "[OKLabel]" +set InstallLabel to "[InstallLabel]" +set AbortLabel to "[AbortLabel]" +set intro to "[IntroText1] + +[IntroText2] + +[IntroText3]" +set chooseMyOwn to "[ChooseMyOwnText]" +set listPrompt to "[ListPromptText]" +set chooseManual to "[ChooseManualText]" +set listOKLabel to "[ListOKLabelText]" +set listCancelLabel to "[ListCancelLabel]" +set appInvalid to "[AppInvalidText1] + +[AppInvalidText2]" -- string will begin with the chosen application's name +set startInstall to "[StartInstallText1] + +[StartInstallText2]" +set IdentifyQ to "[IdentifyQText] + +[IdentifyQText2]" +set IdentifyYES to "[IdentifyYES]" +set IdentifyNO to "[IdentifyNO]" +set installFailed to "[InstallFailedText]" +set installComplete to "[InstallCompleteText] + +[InstallCompleteText2]" + +set sourcedir to (do shell script "dirname " & quoted form of POSIX path of (path to of me)) + +activate +display dialog intro buttons {AbortLabel, InstallLabel} default button 2 + +if (button returned of result) is AbortLabel then + return 2 +end if + +set found_ooos_all to "" +-- command might return an error if spotlight is disabled completely +try + set found_ooos_all to (do shell script "mdfind \"kMDItemContentType == 'com.apple.application-bundle' && kMDItemFSName == '[PRODUCTNAME].app'\"") +end try +set found_ooos_all to found_ooos_all & " +" & chooseMyOwn + +set found_ooos_all_paragraphs to paragraphs in found_ooos_all + +set found_ooos to {} +repeat with currentApp in found_ooos_all_paragraphs + if currentApp does not start with "/Volumes" then + copy currentApp to the end of found_ooos + end if +end repeat + +-- repeat with oneApp in found_ooos +-- display dialog oneApp +-- end repeat + +-- the choice returned is of type "list" +-- Show selection dialog only if more than one or no product was found +-- The first item is an empty string, if no app was found and no app started with "/Volumes" +-- The first item is chooseMyOwn, if no app was found and at least one app started with "/Volumes" +if (get first item of found_ooos as string) is "" then + set the choice to (choose from list found_ooos default items (get second item of found_ooos) with prompt listPrompt OK button name listOKLabel cancel button name listCancelLabel) + if choice is false then + -- do nothing, the user cancelled the installation + return 2 --aborted by user + else if (choice as string) is chooseMyOwn then + -- yeah, one needs to use "choose file", otherwise + -- the user would not be able to select the .app + set the choice to POSIX path of (choose file with prompt chooseManual of type "com.apple.application-bundle" without showing package contents and invisibles) + end if +else if (get first item of found_ooos as string) is chooseMyOwn then + set the choice to (choose from list found_ooos default items (get first item of found_ooos) with prompt listPrompt OK button name listOKLabel cancel button name listCancelLabel) + if choice is false then + -- do nothing, the user cancelled the installation + return 2 --aborted by user + else if (choice as string) is chooseMyOwn then + -- yeah, one needs to use "choose file", otherwise + -- the user would not be able to select the .app + set the choice to POSIX path of (choose file with prompt chooseManual of type "com.apple.application-bundle" without showing package contents and invisibles) + end if +else if (get second item of found_ooos as string) is chooseMyOwn then + -- set choice to found installation + -- set the choice to (get first paragraph of found_ooos) + set the choice to (get first item of found_ooos) +else + set the choice to (choose from list found_ooos default items (get first item of found_ooos) with prompt listPrompt OK button name listOKLabel cancel button name listCancelLabel) + if choice is false then + -- do nothing, the user cancelled the installation + return 2 --aborted by user + else if (choice as string) is chooseMyOwn then + -- yeah, one needs to use "choose file", otherwise + -- the user would not be able to select the .app + set the choice to POSIX path of (choose file with prompt chooseManual of type "com.apple.application-bundle" without showing package contents and invisibles) + end if +end if + +-- now only check whether the path is really from [PRODUCTNAME] +try + do shell script "mdls --raw --name kMDItemFSName --name kMDItemVersion " & quoted form of (choice as string) & " | xargs -0 | fgrep '[PRODUCTNAME].app [PRODUCTVERSION]'" +on error + display dialog (choice as string) & appInvalid buttons {InstallLabel} default button 1 with icon 0 + return 3 --wrong target-directory +end try + +(* +display dialog startInstall buttons {AbortLabel, InstallLabel} default button 2 + +if (button returned of result) is AbortLabel then + return 2 +end if +*) + +-- touch extensions folder to have LO register bundled dictionaries +set tarCommand to "/usr/bin/tar -C " & quoted form of (choice as string) & " -xjf " & quoted form of sourcedir & "/tarball.tar.bz2 && touch " & quoted form of (choice as string) & "/Contents/Resources/extensions" +try + (* A start of unchanged LO must take place so Gatekeeper will verify + the signature prior to installing the languagepack + *) + set apppath to POSIX path of choice + if application apppath is not running then + -- this will flash the startcenter once... + tell application apppath to activate + tell application apppath to quit + end if + do shell script tarCommand + +on error errMSG number errNUM + display dialog IdentifyQ buttons {IdentifyYES, IdentifyNO} with icon 2 + if (button returned of result) is IdentifyYES then + try + do shell script tarCommand with administrator privileges + on error errMSG number errNUM + display dialog installFailed buttons {OKLabel} default button 1 with icon 0 + -- -60005 username/password wrong + -- -128 aborted by user + -- 2 error from tar - tarball not found (easy to test) + return errNUM + end try + else + return 2 -- aborted by user + end if +end try + +display dialog installComplete buttons {OKLabel} default button 1 diff --git a/setup_native/scripts/uninstall_linux.sh b/setup_native/scripts/uninstall_linux.sh new file mode 100644 index 000000000..d0f062c50 --- /dev/null +++ b/setup_native/scripts/uninstall_linux.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + +# Linux deinstallation +# No parameter required, all RPMs listed in $HOME/.RPM_OFFICEDATABASE +# will be removed. + +if [ $# -ne 1 ] +then + echo + echo "Usage:" $0 "<office-installation-dir>" + echo " <inst-destination-dir>: directory where the office to be removed is installed" + echo + exit 2 +fi + +INSTALLDIR=$1 + +# Check for old style .RPM_OFFICEDATABASE first +if [ -d ${INSTALLDIR}/.RPM_OFFICEDATABASE ]; then + RPM_DB_PATH=${INSTALLDIR}/.RPM_OFFICEDATABASE +else + RPM_DB_PATH=${INSTALLDIR}/.RPM_DATABASE +fi + +# the RPM_DB_PATH must be absolute +if [ ! "${RPM_DB_PATH:0:1}" = "/" ]; then + RPM_DB_PATH=`cd ${RPM_DB_PATH}; pwd` +fi + +RPMLIST=`rpm --dbpath $RPM_DB_PATH --query --all` + +# Output ... +clear +echo "#########################################" +echo "# Deinstallation of Office RPMs #" +echo "#########################################" +echo +echo "Path to the RPM database: " $RPM_DB_PATH +echo "RPMs to deinstall:" +echo "$RPMLIST" +echo "====================================================================" +echo + +# Restore original bootstraprc +mv -f $1/program/bootstraprc.orig $1/program/bootstraprc + +rpm --dbpath $RPM_DB_PATH --erase $RPMLIST || exit 2 + +echo "Removing RPM database ..." +rm -rf $RPM_DB_PATH + +echo +echo "Deinstallation done." + +exit 0 diff --git a/setup_native/scripts/unpack_update.sh b/setup_native/scripts/unpack_update.sh new file mode 100644 index 000000000..1af4865cd --- /dev/null +++ b/setup_native/scripts/unpack_update.sh @@ -0,0 +1,50 @@ +#!/bin/sh +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + +EXTENSION=`expr "//$1" : '.*\/.*\.\(t.*\)'` +[ -z $EXTENSION ] && ( echo "Unable to determine file type"; exit 2 ) + +BASEDIR=`dirname "$1"` +FOLDER=`basename "$1" ".$EXTENSION"` +NUM=1 + +DESTPATH="$BASEDIR/$FOLDER" + +while [ -d "$DESTPATH" ]; do + NUM=$(expr $NUM + 1) + DESTPATH="$BASEDIR/$FOLDER-$NUM" +done + +mkdir "$DESTPATH" +cd "$DESTPATH" + +if [ "$EXTENSION" = "tar.gz" -o "$EXTENSION" = "tgz" ]; then + if [ -x /usr/bin/gzcat ]; then + /usr/bin/gzcat "$1" | tar -xf - + else + tar -xzf "$1" + fi +elif [ "$EXTENSION" = "tar.bz2" -o "$EXTENSION" = "tbz2" ]; then + /usr/bin/bzcat "$1" | tar -xf - +else + echo "Unsupported type of archive" + exit 2 +fi + +UPDATE=$(eval ls ./*/update) && SUBFOLDER=$(dirname $UPDATE) && mv $SUBFOLDER/* . && rmdir $SUBFOLDER && echo "$DESTPATH/update" |