1#
2# This file is part of the LibreOffice project.
3#
4# This Source Code Form is subject to the terms of the Mozilla Public
5# License, v. 2.0. If a copy of the MPL was not distributed with this
6# file, You can obtain one at http://mozilla.org/MPL/2.0/.
7#
8# This file incorporates work covered by the following license notice:
9#
10#   Licensed to the Apache Software Foundation (ASF) under one or more
11#   contributor license agreements. See the NOTICE file distributed
12#   with this work for additional information regarding copyright
13#   ownership. The ASF licenses this file to you under the Apache
14#   License, Version 2.0 (the "License"); you may not use this file
15#   except in compliance with the License. You may obtain a copy of
16#   the License at http://www.apache.org/licenses/LICENSE-2.0 .
17#
18
19package installer::download;
20
21use strict;
22use warnings;
23
24use File::Spec;
25use installer::exiter;
26use installer::files;
27use installer::globals;
28use installer::logger;
29use installer::pathanalyzer;
30use installer::remover;
31use installer::systemactions;
32
33BEGIN { # This is needed so that cygwin's perl evaluates ACLs
34    # (needed for correctly evaluating the -x test.)
35    if( $^O =~ /cygwin/i ) {
36        require filetest; import filetest "access";
37    }
38}
39
40##################################################################
41# Including the lowercase product name into the script template
42##################################################################
43
44sub put_productname_into_script
45{
46    my ($scriptfile, $variableshashref) = @_;
47
48    my $productname = $variableshashref->{'PRODUCTNAME'};
49    $productname = lc($productname);
50    $productname =~ s/\.//g;    # openoffice.org -> openofficeorg
51    $productname =~ s/\s*//g;
52
53    my $infoline = "Adding productname $productname into download shell script\n";
54    push( @installer::globals::logfileinfo, $infoline);
55
56    for ( my $i = 0; $i <= $#{$scriptfile}; $i++ )
57    {
58        ${$scriptfile}[$i] =~ s/PRODUCTNAMEPLACEHOLDER/$productname/;
59    }
60}
61
62#########################################################
63# Including the linenumber into the script template
64#########################################################
65
66sub put_linenumber_into_script
67{
68    my ( $scriptfile ) = @_;
69
70    my $linenumber =  $#{$scriptfile} + 2;
71
72    my $infoline = "Adding linenumber $linenumber into download shell script\n";
73    push( @installer::globals::logfileinfo, $infoline);
74
75    for ( my $i = 0; $i <= $#{$scriptfile}; $i++ )
76    {
77        ${$scriptfile}[$i] =~ s/LINENUMBERPLACEHOLDER/$linenumber/;
78    }
79}
80
81#########################################################
82# Determining the name of the new scriptfile
83#########################################################
84
85sub determine_scriptfile_name
86{
87    my ( $filename ) = @_;
88
89    $installer::globals::downloadfileextension = ".sh";
90    $filename = $filename . $installer::globals::downloadfileextension;
91    $installer::globals::downloadfilename = $filename;
92
93    my $infoline = "Setting download shell script file name to $filename\n";
94    push( @installer::globals::logfileinfo, $infoline);
95
96    return $filename;
97}
98
99#########################################################
100# Saving the script file in the installation directory
101#########################################################
102
103sub save_script_file
104{
105    my ($directory, $newscriptfilename, $scriptfile) = @_;
106
107    $newscriptfilename = $directory . $installer::globals::separator . $newscriptfilename;
108    installer::files::save_file($newscriptfilename, $scriptfile);
109
110    my $infoline = "Saving script file $newscriptfilename\n";
111    push( @installer::globals::logfileinfo, $infoline);
112
113    if ( ! $installer::globals::iswindowsbuild )
114    {
115        chmod 0775, $newscriptfilename;
116    }
117
118    return $newscriptfilename;
119}
120
121#########################################################
122# Including checksum and size into script file
123#########################################################
124
125sub put_checksum_and_size_into_script
126{
127    my ($scriptfile, $sumout) = @_;
128
129    my $checksum = "";
130    my $size = "";
131
132    if  ( $sumout =~ /^\s*(\d+)\s+(\d+)\s*$/ )
133    {
134        $checksum = $1;
135        $size = $2;
136    }
137    else
138    {
139        installer::exiter::exit_program("ERROR: Incorrect return value from /usr/bin/sum: $sumout", "put_checksum_and_size_into_script");
140    }
141
142    my $infoline = "Adding checksum $checksum and size $size into download shell script\n";
143    push( @installer::globals::logfileinfo, $infoline);
144
145    for ( my $i = 0; $i <= $#{$scriptfile}; $i++ )
146    {
147        ${$scriptfile}[$i] =~ s/CHECKSUMPLACEHOLDER/$checksum/;
148        ${$scriptfile}[$i] =~ s/DISCSPACEPLACEHOLDER/$size/;
149    }
150
151}
152
153#########################################################
154# Determining checksum and size of tar file
155#########################################################
156
157sub call_sum
158{
159    my ($filename) = @_;
160
161    my $systemcall = "/usr/bin/sum $filename |";
162
163    my $sumoutput = "";
164
165    open (SUM, "$systemcall");
166    $sumoutput = <SUM>;
167    close (SUM);
168
169    my $returnvalue = $?;   # $? contains the return value of the systemcall
170
171    my $infoline = "Systemcall: $systemcall\n";
172    push( @installer::globals::logfileinfo, $infoline);
173
174    if ($returnvalue)
175    {
176        $infoline = "ERROR: Could not execute \"$systemcall\"!\n";
177        push( @installer::globals::logfileinfo, $infoline);
178    }
179    else
180    {
181        $infoline = "Success: Executed \"$systemcall\" successfully!\n";
182        push( @installer::globals::logfileinfo, $infoline);
183    }
184
185    $sumoutput =~ s/\s+$filename\s$//;
186    return $sumoutput;
187}
188
189#########################################################
190# Include the tar file into the script
191#########################################################
192
193sub include_tar_into_script
194{
195    my ($scriptfile, $temporary_tarfile) = @_;
196
197    my $systemcall = "cat $temporary_tarfile >> $scriptfile && rm $temporary_tarfile";
198    my $returnvalue = system($systemcall);
199
200    my $infoline = "Systemcall: $systemcall\n";
201    push( @installer::globals::logfileinfo, $infoline);
202
203    if ($returnvalue)
204    {
205        $infoline = "ERROR: Could not execute \"$systemcall\"!\n";
206        push( @installer::globals::logfileinfo, $infoline);
207    }
208    else
209    {
210        $infoline = "Success: Executed \"$systemcall\" successfully!\n";
211        push( @installer::globals::logfileinfo, $infoline);
212    }
213    return $returnvalue;
214}
215
216#########################################################
217# Create a tar file from the binary package
218#########################################################
219
220sub tar_package
221{
222    my ( $installdir, $tarfilename, $usefakeroot) = @_;
223
224    my $fakerootstring = "";
225    if ( $usefakeroot ) { $fakerootstring = "fakeroot"; }
226
227    my $systemcall = "cd $installdir; $fakerootstring tar -cf - * > $tarfilename";
228
229    my $returnvalue = system($systemcall);
230
231    my $infoline = "Systemcall: $systemcall\n";
232    push( @installer::globals::logfileinfo, $infoline);
233
234    if ($returnvalue)
235    {
236        $infoline = "ERROR: Could not execute \"$systemcall\"!\n";
237        push( @installer::globals::logfileinfo, $infoline);
238    }
239    else
240    {
241        $infoline = "Success: Executed \"$systemcall\" successfully!\n";
242        push( @installer::globals::logfileinfo, $infoline);
243    }
244
245    chmod 0775, $tarfilename;
246
247    return ( -s $tarfilename );
248}
249
250#########################################################
251# Setting installation languages
252#########################################################
253
254sub get_downloadname_language
255{
256    my ($languagestringref) = @_;
257
258    my $languages = $$languagestringref;
259
260    if ( $installer::globals::added_english )
261    {
262        $languages =~ s/en-US_//;
263        $languages =~ s/_en-US//;
264    }
265
266    # do not list languages if there are too many
267    if ( length ($languages) > $installer::globals::max_lang_length )
268    {
269        $languages = '';
270    }
271
272    # do not list pure en-US, except for helppack and langpack
273    if ( ( $languages eq "en-US" ) &&
274         ( ! $installer::globals::languagepack ) &&
275         ( ! $installer::globals::helppack ) )
276    {
277        $languages = '';
278    }
279
280    return $languages;
281}
282
283#########################################################
284# Setting download name
285#########################################################
286
287sub get_downloadname_productname
288{
289    my ($allvariables) = @_;
290
291    my $start = "";
292
293    $start = $allvariables->{'PRODUCTNAME'};
294
295    return $start;
296}
297
298#########################################################
299# Setting download version
300#########################################################
301
302sub get_download_version
303{
304    my ($allvariables) = @_;
305
306    my $version = "";
307
308    $version = $allvariables->{'PRODUCTVERSION'};
309    if (( $allvariables->{'PRODUCTEXTENSION'} ) && ( $allvariables->{'PRODUCTEXTENSION'} ne "" )) { $version = $version . $allvariables->{'PRODUCTEXTENSION'}; }
310
311    return $version;
312}
313
314#################################################################
315# Setting the platform name for download
316#################################################################
317
318sub get_download_platformname
319{
320    my $platformname = "";
321
322    if ( $installer::globals::islinuxbuild )
323    {
324        $platformname = "Linux";
325    }
326    elsif ( $installer::globals::issolarisbuild )
327    {
328        $platformname = "Solaris";
329    }
330    elsif ( $installer::globals::iswindowsbuild )
331    {
332        $platformname = "Win";
333    }
334    elsif ( $installer::globals::isfreebsdbuild )
335    {
336        $platformname = "FreeBSD";
337    }
338    elsif ( $installer::globals::ismacbuild )
339    {
340        $platformname = "MacOS";
341    }
342    else
343    {
344        $platformname = $installer::globals::os;
345    }
346
347    return $platformname;
348}
349
350#########################################################
351# Setting the architecture for the download name
352#########################################################
353
354sub get_download_architecture
355{
356    my $arch = "";
357
358    if ( $installer::globals::issolarissparcbuild )
359    {
360        $arch = "Sparc";
361    }
362    elsif ( $installer::globals::issolarisx86build )
363    {
364        $arch = "x86";
365    }
366    elsif ( $installer::globals::iswindowsbuild )
367    {
368        if ( $installer::globals::iswin64build )
369        {
370            $arch = "x64";
371        }
372        else
373        {
374            $arch = "x86";
375        }
376    }
377    elsif ( $installer::globals::cpuname eq 'INTEL' )
378    {
379        $arch = "x86";
380    }
381    elsif ( $installer::globals::cpuname eq 'POWERPC' )
382    {
383        $arch = "PPC";
384    }
385    elsif ( $installer::globals::cpuname eq 'POWERPC64' )
386    {
387        $arch = "PPC";
388    }
389    elsif ( $installer::globals::cpuname eq 'X86_64' )
390    {
391        $arch = "x86-64";
392    }
393    elsif ( $installer::globals::cpuname eq 'AARCH64' )
394    {
395        $arch = "aarch64";
396    }
397
398    return $arch;
399}
400
401#########################################################
402# Setting the content type for the download name
403#########################################################
404
405sub get_download_content
406{
407    my ($allvariables) = @_;
408
409    my $content = "";
410
411    # content type included in the installer
412    if ( $installer::globals::isrpmbuild )
413    {
414        $content = "rpm";
415    }
416    elsif ( $installer::globals::isdebbuild )
417    {
418        $content = "deb";
419    }
420    elsif ( $installer::globals::packageformat eq "archive" )
421    {
422        $content = "archive";
423    }
424
425    return $content;
426}
427
428#########################################################
429# Setting the functionality type for the download name
430#########################################################
431
432sub get_download_functionality
433{
434    my ($allvariables) = @_;
435
436    my $functionality = "";
437
438    if ( $installer::globals::languagepack )
439    {
440        $functionality = "langpack";
441    }
442    elsif ( $installer::globals::helppack )
443    {
444        $functionality = "helppack";
445    }
446    elsif ( $allvariables->{'POSTVERSIONEXTENSION'} eq "SDK" )
447    {
448        $functionality = "sdk";
449    }
450    elsif ( $allvariables->{'POSTVERSIONEXTENSION'} eq "TEST" )
451    {
452        $functionality = "test";
453    }
454    elsif ( $allvariables->{'PRODUCTNAME'} eq "URE" )
455    {
456        $functionality = "ure";
457    }
458
459    return $functionality;
460}
461
462###############################################################################################
463# Setting the download file name
464# Syntax:
465# (PRODUCTNAME)_(VERSION)_(OS)_(ARCH)_(INSTALLTYPE)_(LANGUAGE).(FILEEXTENSION)
466###############################################################################################
467
468sub set_download_filename
469{
470    my ($languagestringref, $allvariables) = @_;
471
472    my $start = get_downloadname_productname($allvariables);
473    my $versionstring = get_download_version($allvariables);
474    my $platform = get_download_platformname();
475    my $architecture = get_download_architecture();
476    my $content = get_download_content($allvariables);
477    my $functionality = get_download_functionality($allvariables);
478    my $language = get_downloadname_language($languagestringref);
479
480    # Setting the extension happens automatically
481
482    my $filename = $start . "_" . $versionstring . "_" . $platform . "_" . $architecture . "_" . $content . "_" . $functionality . "_" . $language;
483
484    # get rid of duplicit "_" delimiters when some strings are empty
485    $filename =~ s/\_\_\_/\_/g;
486    $filename =~ s/\_\_/\_/g;
487    $filename =~ s/\_\s*$//;
488
489    $installer::globals::ooodownloadfilename = $filename;
490
491    return $filename;
492}
493
494
495#########################################################
496# Creating a tar.gz file
497#########################################################
498
499sub create_tar_gz_file_from_directory
500{
501    my ($installdir, $usefakeroot, $downloaddir, $downloadfilename) = @_;
502
503    my $infoline = "";
504
505    my $packdir = $installdir;
506    installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$packdir);
507    my $changedir = $installdir;
508    installer::pathanalyzer::get_path_from_fullqualifiedname(\$changedir);
509
510    my $fakerootstring = "";
511    if ( $usefakeroot ) { $fakerootstring = "fakeroot"; }
512
513    $installer::globals::downloadfileextension = ".tar.gz";
514    $installer::globals::downloadfilename = $downloadfilename . $installer::globals::downloadfileextension;
515    my $targzname = $downloaddir . $installer::globals::separator . $installer::globals::downloadfilename;
516
517    # fdo#67060 - install script is for RPM only
518    if ( -e "$installdir/install" && !$installer::globals::isrpmbuild )
519    {
520        unlink("$installdir/install");
521    }
522
523    my $systemcall = "cd $changedir; $fakerootstring tar -cf - $packdir | gzip > $targzname";
524
525    my $returnvalue = system($systemcall);
526
527    $infoline = "Systemcall: $systemcall\n";
528    push( @installer::globals::logfileinfo, $infoline);
529
530    if ($returnvalue)
531    {
532        $infoline = "ERROR: Could not execute \"$systemcall\"!\n";
533        push( @installer::globals::logfileinfo, $infoline);
534    }
535    else
536    {
537        $infoline = "Success: Executed \"$systemcall\" successfully!\n";
538        push( @installer::globals::logfileinfo, $infoline);
539    }
540
541    return $targzname;
542}
543
544##############################################################
545# Returning the complete block in all languages
546# for a specified string
547##############################################################
548
549sub get_language_block_from_language_file
550{
551    my ($searchstring, $languagefile) = @_;
552
553    my @language_block = ();
554
555    for ( my $i = 0; $i <= $#{$languagefile}; $i++ )
556    {
557        if ( ${$languagefile}[$i] =~ /^\s*\[\s*$searchstring\s*\]\s*$/ )
558        {
559            my $counter = $i;
560
561            push(@language_block, ${$languagefile}[$counter]);
562            $counter++;
563
564            while (( $counter <= $#{$languagefile} ) && (!( ${$languagefile}[$counter] =~ /^\s*\[/ )))
565            {
566                push(@language_block, ${$languagefile}[$counter]);
567                $counter++;
568            }
569
570            last;
571        }
572    }
573
574    return \@language_block;
575}
576
577##############################################################
578# Returning a specific language string from the block
579# of all translations
580##############################################################
581
582sub get_language_string_from_language_block
583{
584    my ($language_block, $language) = @_;
585
586    my $newstring = "";
587
588    for ( my $i = 0; $i <= $#{$language_block}; $i++ )
589    {
590        if ( ${$language_block}[$i] =~ /^\s*$language\s*\=\s*\"(.*)\"\s*$/ )
591        {
592            $newstring = $1;
593            last;
594        }
595    }
596
597    if ( $newstring eq "" )
598    {
599        $language = "en-US";    # defaulting to english
600
601        for ( my $i = 0; $i <= $#{$language_block}; $i++ )
602        {
603            if ( ${$language_block}[$i] =~ /^\s*$language\s*\=\s*\"(.*)\"\s*$/ )
604            {
605                $newstring = $1;
606                last;
607            }
608        }
609    }
610
611    return $newstring;
612}
613
614####################################################
615# Creating download installation sets
616####################################################
617
618sub create_download_sets
619{
620    my ($installationdir, $includepatharrayref, $allvariableshashref, $downloadname, $languagestringref, $languagesarrayref) = @_;
621
622    my $infoline = "";
623
624    my $force = 1; # print this message even in 'quiet' mode
625    installer::logger::print_message( "\n******************************************\n" );
626    installer::logger::print_message( "... creating download installation set ...\n", $force );
627    installer::logger::print_message( "******************************************\n" );
628
629    installer::logger::include_header_into_logfile("Creating download installation sets:");
630
631    my $firstdir = $installationdir;
632    installer::pathanalyzer::get_path_from_fullqualifiedname(\$firstdir);
633
634    my $lastdir = $installationdir;
635    installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$lastdir);
636
637    if ( $installer::globals::iswindowsbuild && $lastdir =~ /\./ ) { $lastdir =~ s/\./_download_inprogress\./ }
638    else { $lastdir = $lastdir . "_download_inprogress"; }
639
640    # removing existing directory "_native_packed_inprogress" and "_native_packed_witherror" and "_native_packed"
641
642    my $downloaddir = $firstdir . $lastdir;
643
644    if ( -d $downloaddir ) { installer::systemactions::remove_complete_directory($downloaddir); }
645
646    my $olddir = $downloaddir;
647    $olddir =~ s/_inprogress/_witherror/;
648    if ( -d $olddir ) { installer::systemactions::remove_complete_directory($olddir); }
649
650    $olddir = $downloaddir;
651    $olddir =~ s/_inprogress//;
652    if ( -d $olddir ) { installer::systemactions::remove_complete_directory($olddir); }
653
654    # creating the new directory
655
656    installer::systemactions::create_directory($downloaddir);
657
658    $installer::globals::saveinstalldir = $downloaddir;
659
660    # evaluating the name of the download file
661
662    $downloadname = set_download_filename($languagestringref, $allvariableshashref);
663
664    if ( ! $installer::globals::iswindowsbuild )    # Unix specific part
665    {
666
667        # whether to use fakeroot (only required for Solaris and Linux)
668        my $usefakeroot = 0;
669        if (( $installer::globals::issolarisbuild ) || ( $installer::globals::islinuxbuild )) { $usefakeroot = 1; }
670
671        my $downloadfile = create_tar_gz_file_from_directory($installationdir, $usefakeroot, $downloaddir, $downloadname);
672    }
673
674    return $downloaddir;
675}
676
6771;
678