summaryrefslogtreecommitdiff
path: root/Master/install-tl
diff options
context:
space:
mode:
authorReinhard Kotucha <reinhard.kotucha@web.de>2008-04-18 21:30:57 +0000
committerReinhard Kotucha <reinhard.kotucha@web.de>2008-04-18 21:30:57 +0000
commit511e7671a16177fc64d0ee3524d2a18d9b78560d (patch)
tree59e787ee8b3de2de3a3ddd7a4a117820df2da963 /Master/install-tl
parent5fc85818c26984d2efa29bd6969793448c68e8df (diff)
install-tl.pl --> install-tl
git-svn-id: svn://tug.org/texlive/trunk@7501 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/install-tl')
-rwxr-xr-xMaster/install-tl1203
1 files changed, 1203 insertions, 0 deletions
diff --git a/Master/install-tl b/Master/install-tl
new file mode 100755
index 00000000000..83973e7d867
--- /dev/null
+++ b/Master/install-tl
@@ -0,0 +1,1203 @@
+#!/usr/bin/env perl
+
+# $Id$
+# install-tl.pl
+#
+# Copyright 2007 2008 Reinhard Kotucha, Norbert Preining
+# This file is licensed under the GNU General Public License version 2
+# or any later version.
+#
+# TODO:
+# - support option_paper (paper instead of A4)
+# missing
+
+my $svnrev = '$Revision$';
+$svnrev =~ m/: ([0-9]+) /;
+$::installerrevision = $1;
+
+# is now taken from 00texlive.config: release, $tlpdb->config_release;
+our $texlive_release;
+
+BEGIN {
+ $^W = 1;
+ my $me=$0;
+ $me=~s!\\!/!g if $^O=~/^MSWin(32|64)$/i;
+
+ if ($me=~m!/!) {
+ ($::installerdir=$me)=~s!(.*)/.*$!$1!;
+ # we have to chdir to the Master ...
+ chdir($::installerdir);
+ } else {
+ $::installerdir='.';
+ }
+# The installer uses a minimal subset of Perl for Windows. In order
+# to avoid conflicts with other versions of Perl already installed on
+# the system, we simply ignore them. The installer has to execute
+# $::installerdir/tlpkg/bin/perl.exe and should not rely on any other
+# Perl executable.
+
+ if ($^O=~/^MSWin(32|64)$/i) {
+ @INC="$::installerdir/tlpkg/installer/perllib";
+ }
+ unshift (@INC, "$::installerdir/tlpkg");
+}
+
+use TeXLive::TLUtils qw(initialize_installer media platform platform_desc
+ which getenv win32 unix program_exists
+ get_system_tmpdir member
+ mkdirhier make_var_skeleton make_local_skeleton install_package copy
+ install_packages dirname tllog setup_programs);
+use TeXLive::TLPOBJ;
+use TeXLive::TLPDB;
+use TeXLive::TLConfig;
+use Pod::Usage;
+use Cwd 'abs_path';
+
+if (win32) {
+ require TeXLive::TLWinGoo;
+ TeXLive::TLWinGoo->import( qw(
+ &wg_error
+ &win_version
+ &is_vista
+ &admin
+ &non_admin
+ &reg_country
+ &dir_writable
+ &expand_string
+ &global_tmpdir
+ &get_system_path
+ &get_user_path
+ &setenv_reg
+ &unsetenv_reg
+ &add_texbindir_to_path
+ &remove_texbindirs_from_path
+ &register_script_type
+ &unregister_script_type
+ &broadcast_env
+ &update_assocs
+ &register_uninstaller
+ ));
+}
+use Getopt::Long;
+$Getopt::Long::autoabbrev=0;
+
+use strict;
+
+# debugging/logging cmd lines options:
+# -q shut up terminal output
+# -qq shut up also log file output
+# -d set $::LOGLEVELFILE to $::LOG_DEBUG
+# -dd set $::LOGLEVELFILE to $::LOG_DDEBUG
+# -ddd set $::LOGLEVELFILE to $::LOG_DDDEBUG
+#
+$::LOGLEVELFILE = $::LOG_NORMAL;
+$::LOGLEVELTERMINAL = $::LOG_NORMAL;
+@::LOGLINES = ();
+#
+# $install{$packagename} == 1 if it should be installed
+my %install;
+
+# the default scheme to be installed
+my $default_scheme='scheme-full';
+
+# some arrays where the lists of collections to be installed are saved
+# our for menus
+our @collections_std;
+our @collections_lang;
+our @collections_lang_doc;
+# for win dealing
+#our $Registry;
+# The global variable %vars is an associative list which contains all
+# variables and their values which can be changed by the user.
+# needs to be our since TeXLive::TLUtils uses it
+our %vars=( # 'n_' means 'number of'.
+ 'this_platform' => platform(),
+ 'n_systems_available' => 0,
+ 'n_systems_selected' => 0,
+ 'n_collections_selected' => 0,
+ 'n_collections_available' => 0,
+ 'total_size' => 0,
+ 'option_symlinks' => 0,
+ 'sys_bin' => '/usr/local/bin',
+ 'sys_man' => '/usr/local/man',
+ 'sys_info' => '/usr/local/info',
+ 'option_doc' => 1,
+ 'option_src' => 1,
+ 'option_fmt' => 0,
+ 'option_letter' => 0,
+ 'selected_scheme' => $default_scheme,
+ );
+
+# option handling
+my $opt_media = "";
+my $opt_url = "";
+my $opt_profile = "";
+my $opt_no_cls=0;
+my $opt_nogui = 0;
+my $opt_debug = 0;
+my $opt_ddebug = 0;
+my $opt_dddebug = 0;
+my $opt_quiet = 0;
+my $opt_qquiet = 0;
+my $opt_nonadmin = 0;
+my $opt_arch = 0;
+our $opt_portable = 0;
+my $opt_help = 0;
+my $opt_version = 0;
+my $opt_gui = 0;
+$opt_gui = 1 if (win32);
+
+# default language for GUI installer
+$::lang = "en";
+
+GetOptions("media=s" => \$opt_media,
+ "profile=s"=> \$opt_profile,
+ "no-cls",
+ "gui", \$opt_gui,
+ "no-gui", \$opt_nogui,
+ "netarchive=s" => \$NetArchive,
+ "diskarchive=s" => \$DiskArchive,
+ "lang=s" => \$::opt_lang,
+ "print-arch" => \$opt_arch,
+ "portable" => \$opt_portable,
+ "d" => \$opt_debug,
+ "dd" => \$opt_ddebug,
+ "ddd" => \$opt_dddebug,
+ "q" => \$opt_quiet,
+ "qq" => \$opt_qquiet,
+ "url=s" => \$opt_url,
+ "version" => \$opt_version,
+ "help|?" => \$opt_help) or pod2usage(1);
+
+if (win32()) {
+ pod2usage(-exitstatus => 0, -verbose => 2, -noperldoc => 1) if $opt_help;
+} else {
+ pod2usage(-exitstatus => 0, -verbose => 2) if $opt_help;
+}
+
+if ($opt_version) {
+ print "TeX Live Cross Platform Installer, Revision $::installerrevision\n";
+ exit 0;
+}
+
+if (defined($::opt_lang)) {
+ $::lang = $::opt_lang;
+}
+
+if ($opt_quiet) {
+ $::LOGLEVELTERMINAL = $::LOG_ZERO;
+}
+if ($opt_qquiet) {
+ $::LOGLEVELTERMINAL = $::LOG_ZERO;
+ $::LOGLEVELFILE = $::LOG_ZERO;
+}
+if ($opt_debug) {
+ $::LOGLEVELFILE = $::LOG_DEBUG;
+}
+if ($opt_ddebug) {
+ $::LOGLEVELFILE = $::LOG_DDEBUG;
+}
+if ($opt_dddebug) {
+ $::LOGLEVELFILE = $::LOG_DDDEBUG;
+}
+if ("$opt_media" =~ m/^CD/i) {
+ $::_media_ = "CD";
+} elsif ("$opt_media" =~ m/^NET/i) {
+ $::_media_ = "NET";
+} elsif ("$opt_media" =~ m/^DVD/i) {
+ $::_media_ = "DVD";
+}
+
+if ("$opt_profile" ne "") {
+ if (-r "$opt_profile") {
+ tllog($::LOG_NORMAL, "Using automated installation using $opt_profile!");
+ } else {
+ $opt_profile = "";
+ tllog($::LOG_NORMAL, "Profile $opt_profile not readable, continuing in interactive mode!");
+ }
+}
+
+if ($opt_nonadmin and win32()) { non_admin(); }
+
+if ("$opt_url" ne "") {
+ $TeXLiveURL = "$opt_url";
+}
+
+# the TLPDB instances we will use. $tlpdb is for the one from the installation
+# media, while $localtlpdb is for the new installation
+# $tlpdb must be our because it is used in install-menu-text.pl
+our $tlpdb;
+my $localtlpdb;
+
+# $finished == 1 if the menu call already did the installation
+my $finished = 0;
+@::start_install_hook = ();
+@::end_install_hook = ();
+@::start_postinst_hook = ();
+@::start_install_hook = ();
+
+my $system_tmpdir=get_system_tmpdir();
+
+if ($opt_arch) {
+ print platform;
+ exit 0;
+} elsif ($opt_portable) {
+ $::LOGLEVELTERMINAL = $::LOG_ZERO;
+ # initialize_installer:
+ $::_media_ = "DVD";
+ $::_platform_ = platform();
+ $vars{'TEXDIR'} = getenv('TEXDIR');
+ if (not -d $vars{'TEXDIR'}.'/bin/'.$::_platform_) { # shouldn't happen
+ print "Platform ".$::_platform_." not supported\n";
+ exit 1;
+ }
+ # set_platforms_supported();
+ # set_texlive_default_dirs();
+ $vars{'TEXMFSYSVAR'} = getenv('TEXMFSYSVAR');
+ $vars{'TEXMFSYSCONFIG'} = getenv('TEXMFSYSCONFIG');
+ $vars{'TEXMFLOCAL'} = getenv('TEXMFLOCAL');
+ $vars{'TEXMFHOME'} = getenv('TEXMFHOME');
+ $vars{'TEXMFVAR'} = getenv('TEXMFVAR');
+ $vars{'TEXMFCONFIG'} = getenv('TEXMFCONFIG');
+ # initialize_collections();
+ # set_install_platform();
+ $vars{'this_platform'} = platform();
+ # do_installation();
+ # prepare_installation();
+ if (win32()) {
+ non_admin();
+ my $winpath = "$vars{'TEXDIR'}/bin/win32";
+ register_script_type(".texlua", "%TEXBINDIR%/texlua.exe");
+ update_assocs();
+ }
+ mkdirhier "$vars{'TEXMFCONFIG'}";
+ if (not -d "$vars{'TEXMFSYSVAR'}" ) {
+ print "About to generate some files... Press <enter>";
+ <STDIN>;
+ load_tlpdb();
+ $localtlpdb = $tlpdb;
+ $texlive_release = $tlpdb->config_release;
+ make_var_skeleton "$vars{'TEXMFSYSVAR'}";
+ #$localtlpdb=new TeXLive::TLPDB;
+ #$localtlpdb->root("$vars{'TEXDIR'}");
+ do_postinst_stuff();
+ }
+ close($::LOGFILE) if defined($::LOGFILE);
+ exit 0;
+}
+
+tllog($::LOG_NORMAL, "Platform: ", platform, " => \'", platform_desc(platform), "\'\n");
+if (media() eq "DVD") {
+ tllog($::LOG_NORMAL, "Distribution: live (uncompressed)\n");
+} elsif (media() eq "CD") {
+ tllog($::LOG_NORMAL, "Distribution: inst (compressed)\n");
+} elsif (media() eq "NET") {
+ tllog($::LOG_NORMAL, "Distribution: net (downloading)\n");
+} else {
+ tllog($::LOG_NORMAL, "Distribution: ", media(), "\n");
+}
+tllog($::LOG_NORMAL, "Directory for Temporary Files: '", $system_tmpdir, "\'\n");
+tllog($::LOG_NORMAL, "Installer Directory: '$::installerdir'\n");
+
+initialize_installer();
+setup_programs("$::installerdir/tlpkg/installer", "$::_platform_");
+load_tlpdb();
+$texlive_release = $tlpdb->config_release;
+set_platforms_supported();
+set_texlive_default_dirs();
+initialize_collections();
+set_install_platform();
+if ($opt_profile eq "") {
+ # do the normal interactive installation!
+ #
+ # here we could load different menu systems. Currently several things
+ # are "our" so that the menu implementation can use it. The $tlpdb, the
+ # %var, and all the @collection*
+ # install-menu-*.pl should implement a function run_menu() and should
+ # change ONLY stuff in %vars
+ # The allowed keys in %vars should be specified somewhere ...
+ # the menu implementation should return
+ # MENU_INSTALL do the installation
+ # MENU_ABORT abort every action immediately, no cleanup
+ # MENU_QUIT try to quit and clean up mess
+ our $MENU_INSTALL = 0;
+ our $MENU_ABORT = 1;
+ our $MENU_QUIT = 2;
+ our $MENU_ALREADYDONE = 3;
+ if ($opt_gui && !$opt_nogui) {
+ # try to load Tk.pm, but don't die if it doesn't work
+ eval { require Tk; };
+ if ($@) {
+ # that didn't work out, so warn the user and continue with text mode
+ tllog($::LOG_NORMAL, "Cannot load Tk, maybe something is missing!\n");
+ tllog($::LOG_NORMAL, "Error message from loading Tk:\n");
+ tllog($::LOG_NORMAL, "$@\n");
+ tllog($::LOG_NORMAL, "Continuing in Text Mode...\n");
+ $opt_gui = 0;
+ }
+ }
+ if ($opt_gui && !$opt_nogui) {
+ require("installer/install-menu-perltk.pl");
+ } else {
+ require("installer/install-menu-text.pl");
+ }
+ my $ret = run_menu();
+ if ($ret == $MENU_QUIT) {
+ # do_cleanup(); MISSING
+ flushlog();
+ exit(1);
+ }
+ if ($ret == $MENU_ABORT) {
+ # NO do_cleanup()!
+ flushlog();
+ exit(2);
+ }
+ if ($ret == $MENU_ALREADYDONE) {
+ tllog($::LOG_DEBUG, "run_menu has already done the work ... cleaning up!\n");
+ $finished = 1;
+ }
+ if (!$finished && ($ret != $MENU_INSTALL)) {
+ tllog($::LOG_NORMAL, "Unknown return value of run_menu: $ret\n");
+ exit(3);
+ }
+} else {
+ read_profile("$opt_profile");
+}
+
+if (!$finished) {
+ # do the actual installation
+ do_installation();
+}
+
+# now open the log file and write out the log lines
+# try to open a log file
+if ($::LOGLEVELFILE > $::LOG_ZERO) {
+ if (open(LOGF,">$vars{'TEXDIR'}/install-tl.log")) {
+ $::LOGFILE = \*LOGF;
+ foreach my $line(@::LOGLINES) {
+ print $::LOGFILE "$line";
+ }
+ } else {
+ warn("Cannot create log file $vars{'TEXDIR'}/install-tl.log: $!\nNot writing out log lines!\n");
+ $::LOGLEVELFILE = $::LOG_ZERO;
+ }
+}
+
+# dump various things to the log file
+if (defined($::LOGFILE)) {
+ print $::LOGFILE "\nDump of vars:\n";
+ foreach my $key (keys %vars) {
+ print $::LOGFILE "$key $vars{$key}\n";
+ }
+ create_profile($::LOGFILE);
+}
+
+dump_vars("$system_tmpdir/texlive.vars");
+
+# write the profile out
+create_profile("$vars{'TEXDIR'}/$InfraLocation/texlive.profile");
+tllog($::LOG_DEBUG, "Profile written to $vars{'TEXDIR'}/$InfraLocation/texlive.profile\n");
+
+# Close log file if present
+close($::LOGFILE) if defined($::LOGFILE);
+
+
+exit(0);
+
+###################################################################
+#
+# FROM HERE ON ONLY SUBROUTINES
+# NO VARIABLE DECLARATIONS
+#
+###################################################################
+
+sub do_installation {
+ # do the actual installation
+ foreach my $h (@::start_install_hook) {
+ &$h();
+ }
+ calc_depends();
+ prepare_installation();
+ save_options_into_tlpdb();
+ do_install_packages();
+ if (win32()) {
+ do_win_registry_magic();
+ }
+ foreach my $h (@::start_postinst_hook) {
+ &$h();
+ }
+ do_postinst_stuff();
+ $localtlpdb->save;
+ foreach my $h (@::end_install_hook) {
+ &$h();
+ }
+}
+
+sub dump_vars {
+ my $filename=shift;
+ my $fh;
+ if (ref($filename)) {
+ $fh = $filename;
+ } else {
+ open VARS, ">$filename";
+ $fh = \*VARS;
+ }
+ foreach my $key (keys %vars) {
+ print $fh "$key $vars{$key}\n";
+ }
+ close VARS if (!ref($filename));
+ tllog($::LOG_DEBUG, "\n%vars dumped to '$filename'.\n");
+}
+
+
+# Determine which platforms are supported.
+sub set_platforms_supported {
+ my @binaries = $tlpdb->available_architectures;
+ for my $binary (@binaries) {
+ unless (defined $vars{"binary_$binary"}) {
+ $vars{"binary_$binary"}=0;
+ }
+ }
+ for my $key (keys %vars) {
+ ++$vars{'n_systems_available'} if ($key=~/^binary/);
+ }
+}
+
+# Environment variables and default values on UNIX:
+# TEXLIVE_INSTALL_PREFIX /usr/local/texlive => $tex_prefix
+# TEXLIVE_INSTALL_TEXDIR $tex_prefix/2007 => $TEXDIR
+# TEXLIVE_INSTALL_TEXMFSYSVAR $TEXDIR/texmf-var
+# TEXLIVE_INSTALL_TEXMFLOCAL $tex_prefix/texmf-local
+# TEXLIVE_INSTALL_TEXMFHOME '$HOME/texmf'
+
+sub set_texlive_default_dirs {
+ my $tex_prefix;
+ my $texmfsysvar;
+ my $texmflocal;
+ my $texmfhome;
+
+ $tex_prefix=getenv('TEXLIVE_INSTALL_PREFIX');
+ if (win32) {
+ my $prog = getenv('ProgramFiles');
+ $tex_prefix ||= $prog . '/texlive';
+ # $tex_prefix ||= $prog . '/texlive' if TeXLive::TLWinGoo::dir_writable($prog);
+ # $tex_prefix||=getenv('USERPROFILE') . '/texlive';
+ } else {
+ $tex_prefix||='/usr/local/texlive';
+ }
+ $vars{'TEXDIR'}="$tex_prefix/$texlive_release";
+
+ $texmfsysvar=getenv('TEXLIVE_INSTALL_TEXMFSYSVAR');
+ $texmfsysvar||=$vars{'TEXDIR'} . '/texmf-var';
+ $vars{'TEXMFSYSVAR'}="$texmfsysvar";
+
+ $texmflocal=getenv('TEXLIVE_INSTALL_TEXMFLOCAL');
+ $texmflocal||="$tex_prefix/texmf-local";
+ $vars{'TEXMFLOCAL'}="$texmflocal";
+
+ $texmfhome=getenv('TEXLIVE_INSTALL_TEXMFHOME');
+ $texmfhome ||= "~";
+ $vars{'TEXMFHOME'}="$texmfhome/texmf";
+}
+
+sub calc_depends {
+ # we have to reset the install hash EVERY TIME otherwise everything will
+ # always be installed since the default is scheme-full which selects
+ # all packages and never deselects it
+ %install=();
+
+ # initialize the %install hash with what should be installed
+
+ # First look for packages in the selected scheme.
+ my $scheme=$tlpdb->get_package($vars{'selected_scheme'});
+ if (!defined($scheme)) {
+ dump_vars(\*STDOUT);
+ die ("Scheme $vars{'selected_scheme'} not defined!\n");
+ }
+
+ for my $scheme_content ($scheme->depends) {
+ $install{"$scheme_content"}=1 unless ($scheme_content=~/^collection-/);
+ }
+
+ # Now look for collections in the %vars hash. These are not
+ # necessarily the collections required by a scheme. The final
+ # decision is made in the collections/languages menu.
+ foreach my $key (keys %vars) {
+ if ($key=~/^collection-/) {
+ $install{$key} = 1 if $vars{$key};
+ }
+ }
+
+ # compute the list of archs to be installed
+ my @archs;
+ foreach (keys %vars) {
+ if (m/^binary_(.*)$/ ) {
+ if ($vars{$_}) { push @archs, $1; }
+ }
+ }
+
+ # if programs for arch=win32 are installed we also have to install
+ # bin-tlperl.win32 which provides the "hidden" perl that will be used
+ # to run all the perl scripts.
+ # Furthermore we install bin-tlgs.win32, too
+ if (grep(/^win32$/,@archs)) {
+ $install{"bin-tlperl.win32"} = 1;
+ $install{"bin-tlgs.win32"} = 1;
+ }
+
+ # loop over all the packages until it is getting stable
+ my $changed = 1;
+ while ($changed) {
+ # set $changed to 0
+ $changed = 0;
+
+ # collect the already selected packages
+ my @pre_selected = keys %install;
+ tllog($::LOG_DDEBUG, "initial number of installations: $#pre_selected\n");
+
+ # loop over all the pre_selected and add them
+ foreach my $p (@pre_selected) {
+ tllog($::LOG_DDEBUG, "pre_selected $p\n");
+ foreach my $p_dep ($tlpdb->get_package($p)->depends) {
+ if ($p_dep =~ m/^(.*)\.ARCH$/) {
+ my $foo = "$1";
+ foreach my $a (@archs) {
+ $install{"$foo.$a"} = 1;
+ }
+ } elsif ($p_dep =~ m/^(.*)\.win32$/) {
+ # a win32 package should *only* be installed if we are installing
+ # the win32 arch
+ if (grep(/^win32$/,@archs)) {
+ $install{$p_dep} = 1;
+ }
+ } else {
+ $install{$p_dep} = 1;
+ }
+ }
+ }
+
+ # check for newly selected packages
+ my @post_selected = keys %install;
+ tllog($::LOG_DDEBUG, "number of post installations: $#post_selected\n");
+
+ # set repeat condition
+ if ($#pre_selected != $#post_selected) {
+ $changed = 1;
+ }
+ }
+
+ # now do the size computation
+ my $size = 0;
+ foreach my $p (keys %install) {
+ my $tlpobj = $tlpdb->get_package($p);
+ if (not(defined($tlpobj))) {
+ die "Cannot find $p in texlive.tlpdb, strange!\n";
+ }
+ $size+=$tlpobj->docsize if $vars{'option_doc'};
+ $size+=$tlpobj->srcsize if $vars{'option_src'};
+ $size+=$tlpobj->runsize;
+ foreach my $a (@archs) {
+ $size += $tlpobj->binsize->{$a} if defined($tlpobj->binsize->{$a});
+ }
+ }
+ $vars{'total_size'} =
+ sprintf "%d", ($size * $TeXLive::TLConfig::BlockSize)/1024**2;
+}
+
+sub load_tlpdb {
+ my $master;
+ if (media eq 'NET') {
+ $master="$TeXLiveURL";
+ } else {
+ $master="$::installerdir";
+ }
+ tllog($::LOG_NORMAL, "Loading $master/$TeXLive::TLConfig::InfraLocation/$TeXLive::TLConfig::DatabaseName ...\n");
+ $tlpdb=TeXLive::TLPDB->new(root => "$master");
+}
+
+sub initialize_collections {
+ foreach my $pkg ($tlpdb->list_packages) {
+ my $tlpobj = $tlpdb->{'tlps'}{$pkg};
+ if ($tlpobj->category eq "Collection") {
+ $vars{"$pkg"}=0;
+ ++$vars{'n_collections_available'};
+ if ($pkg=~/collection-lang/) {
+ push @collections_lang, $pkg;
+ } elsif ($pkg=~/documentation/) {
+ if ($pkg=~/documentation-base/) {
+ push @collections_std, $pkg;
+ } else {
+ push @collections_lang_doc, $pkg;
+ }
+ } else {
+ push @collections_std, $pkg;
+ }
+ }
+ }
+ my $scheme_tlpobj = $tlpdb->get_package($default_scheme);
+ if (defined ($scheme_tlpobj)) {
+ $vars{'n_collections_selected'}=0;
+ foreach my $dependent ($scheme_tlpobj->depends) {
+ if ($dependent=~/^(collection-.*)/) {
+ $vars{"$1"}=1;
+ ++$vars{'n_collections_selected'};
+ }
+ }
+ }
+}
+
+sub set_install_platform {
+ my @available_platforms;
+ my $detected_platform=platform;
+ my $warn_nobin;
+ my $warn_nobin_x86_64_linux;
+ my $nowarn="";
+ my $wp='##'; # warning prefix
+
+ $warn_nobin="\n$wp WARNING! No binaries for your platform found! ";
+ $warn_nobin_x86_64_linux="$warn_nobin" .
+ "$wp No binaries for x86_64-linux found, using i386-linux instead.\n";
+
+ my $ret = $warn_nobin;
+ if (defined $vars{"binary_$detected_platform"}) {
+ $vars{"binary_$detected_platform"}=1;
+ $vars{'inst_platform'}=$detected_platform;
+ $ret = $nowarn;
+ } elsif ($detected_platform eq 'x86_64-linux') {
+ $vars{'binary_i386-linux'}=1;
+ $vars{'inst_platform'}='i386-linux';
+ $ret = $warn_nobin_x86_64_linux;
+ } else {
+ $ret = $warn_nobin;
+ }
+ foreach my $key (keys %vars) {
+ if ($key=~/^binary.*/) {
+ ++$vars{'n_systems_selected'} if $vars{$key}==1;
+ }
+ }
+ return($ret);
+}
+
+sub create_profile {
+ my $profilepath = shift;
+ # The file "TLprofile" is created at the beginning of the
+ # installation process and contains information about the current
+ # setup. The purpose is to allow non-interactive installations.
+ my $fh;
+ if (ref($profilepath)) {
+ $fh = $profilepath;
+ } else {
+ open PROFILE, ">$profilepath";
+ $fh = \*PROFILE;
+ }
+ my $tim = gmtime(time);
+ print $fh "# texlive.profile written on $tim UTC\n";
+ print $fh "# it will NOT be overwritten and reflects only the\n";
+ print $fh "# installation profile at installation time\n";
+ print $fh "selected_scheme $vars{selected_scheme}\n";
+ foreach my $key (keys %vars) {
+ print $fh "$key $vars{$key}\n"
+ if $key=~/^collection/ and $vars{$key}==1;
+ print $fh "$key $vars{$key}\n" if $key=~/^option_letter/;
+ print $fh "$key $vars{$key}\n" if $key=~/^option_doc/;
+ print $fh "$key $vars{$key}\n" if $key=~/^option_fmt/;
+ print $fh "$key $vars{$key}\n" if $key=~/^option_src/;
+ print $fh "$key $vars{$key}\n" if $key=~/^option_symlinks/;
+ print $fh "$key $vars{$key}\n" if $key=~/^TEXDIR/;
+ print $fh "$key $vars{$key}\n" if $key=~/^TEXMFSYSVAR/;
+ print $fh "$key $vars{$key}\n" if $key=~/^TEXMFLOCAL/;
+ print $fh "$key $vars{$key}\n" if $key=~/^TEXMFHOME/;
+ }
+ if (!ref($profilepath)) {
+ close PROFILE;
+ }
+}
+
+sub read_profile {
+ my $profilepath = shift;
+ open PROFILE, "<$profilepath"
+ or die "Cannot open profile $profilepath for reading!\n";
+ my %pro;
+ while (<PROFILE>) {
+ next if m/^[[:space:]]*$/; # skip empty lines
+ next if m/^[[:space:]]*#/; # skip comment lines
+ my ($k,$v) = split;
+ $pro{$k} = $v;
+ }
+ foreach (keys %vars) {
+ # clear out collections from var
+ if (m/^collection-/) { $vars{$_} = 0; }
+ if (defined($pro{$_})) { $vars{$_} = $pro{$_}; }
+ }
+}
+
+sub prepare_installation {
+ make_var_skeleton "$vars{'TEXMFSYSVAR'}";
+ make_local_skeleton "$vars{'TEXMFLOCAL'}";
+ mkdirhier "$vars{'TEXDIR'}/texmf-config";
+
+ $localtlpdb=new TeXLive::TLPDB;
+ $localtlpdb->root("$vars{'TEXDIR'}");
+}
+
+
+sub do_install_packages {
+ my @what;
+ foreach my $package (sort keys %install) {
+ push @what, $package if ($install{$package} == 1);
+ }
+ install_packages($tlpdb,$localtlpdb,\@what,$vars{'option_src'},$vars{'option_doc'});
+}
+
+# for later complete removal we want to save some options and values
+# into the local tlpdb:
+# - should links be set, and if yes, the destination (bin,man,info)
+sub save_options_into_tlpdb {
+ my $tlp = new TeXLive::TLPOBJ;
+ $tlp->name("00texlive-installation.config");
+ $tlp->category("TLCore");
+ my @deps;
+ push @deps, "platform/$::_platform_";
+ if ($::_media_ eq 'NET') {
+ push @deps, "location/$TeXLiveURL";
+ } else {
+ push @deps, "location/" . abs_path($::installerdir);
+ }
+ if ($vars{'option_letter'}) {
+ push @deps, "letter";
+ }
+ if ($vars{'option_fmt'}) {
+ push @deps, "formats";
+ }
+ if ($vars{'option_symlinks'}) {
+ push @deps, "symlinks";
+ push @deps, "sys_bin/$vars{'sys_bin'}";
+ push @deps, "sys_info/$vars{'sys_info'}";
+ push @deps, "sys_man/$vars{'sys_man'}";
+ }
+ if ($vars{'option_doc'}) {
+ push @deps, "docfiles";
+ }
+ if ($vars{'option_src'}) {
+ push @deps, "srcfiles";
+ }
+ $tlp->depends(@deps);
+ $localtlpdb->add_tlpobj($tlp);
+ $localtlpdb->save();
+}
+
+# do_postinst_stuff has to fix up the texmf tree and install some missing
+# files. The things to do are taken from the install-live.sh installer
+# of former times, and should be critically checked.
+sub do_postinst_stuff {
+ my $TEXDIR="$vars{'TEXDIR'}";
+ my $TEXMFSYSVAR="$vars{'TEXMFSYSVAR'}";
+ my $TEXMFLOCAL="$vars{'TEXMFLOCAL'}";
+
+ # install some copies from texmf(-dist) into texmf-var
+ copy ("$TEXDIR/texmf-dist/tex/plain/config/language.def",
+ "$TEXMFSYSVAR/tex/plain/config")
+ if (-f "$TEXDIR/texmf-dist/tex/plain/config/language.def");
+ copy ("$TEXDIR/texmf/xdvi/XDvi",
+ "$TEXMFSYSVAR/xdvi")
+ if (-f "$TEXDIR/texmf/xdvi/XDvi");
+
+ # those files must exist
+ copy ("$TEXDIR/texmf/dvips/config/config.ps",
+ "$TEXMFSYSVAR/dvips/config");
+ copy ("$TEXDIR/texmf/dvipdfm/config/config",
+ "$TEXMFSYSVAR/dvipdfm/config");
+ copy ("$TEXDIR/texmf/web2c/mktex.cnf",
+ "$TEXMFSYSVAR/web2c");
+
+ # the old installer copied from CDDIR, but shouldn't this be installed
+ # in ANY case since it is in bin-pdftex???
+ copy ("$TEXDIR/texmf/tex/generic/config/pdftexconfig.tex",
+ "$TEXMFSYSVAR/tex/generic/config");
+
+ # old installer did this, should we do this, TOO????
+ #cp $CDDIR/texmf-dist/tex/context/config/cont-usr.tex $TEXMFSYSVAR/tex/context/config/cont-usr.tex
+
+ do_texmf_cnf() unless $opt_portable;
+
+
+ # final program execution
+ # we have to do several things:
+ # - clean the environment from spurious TEXMF related variables
+ # - add the bin dir to the PATH
+ # - select perl interpreter and set the correct perllib
+ # - run the programs
+
+ # Step 1: Clean the environment
+ #my @TMFVARS=qw(VARTEXFONTS TEXMFMAIN TEXMFDIST TEXMFLOCAL TEXMFSYSVAR
+ # TEXMFSYSCONFIG TEXMFHOME TEXMFVAR TEXMFCONFIG TEXMF SYSTEXMF VARTEXFONTS
+ # TEXMFDBS WEB2C TEXINPUTS TEXFORMATS MFBASES MPMEMS TEXPOOL MFPOOL MPPOOL
+ # PSHEADERS TEXFONTMAPS TEXPSHEADERS TEXCONFIG TEXMFCNF);
+ my @TMFVARS0=qw(VARTEXFONTS
+ TEXMF SYSTEXMF VARTEXFONTS
+ TEXMFDBS WEB2C TEXINPUTS TEXFORMATS MFBASES MPMEMS TEXPOOL MFPOOL MPPOOL
+ PSHEADERS TEXFONTMAPS TEXPSHEADERS TEXCONFIG TEXMFCNF);
+ my @TMFVARS1=qw(TEXMFMAIN TEXMFDIST TEXMFLOCAL TEXMFSYSVAR TEXMFSYSCONFIG
+ TEXMFHOME TEXMFVAR TEXMFCONFIG);
+
+ foreach my $tmv (@TMFVARS0) {
+ delete $ENV{$tmv} if (defined($ENV{$tmv}));
+ }
+ if (!$opt_portable) { foreach my $tmv (@TMFVARS1) {
+ delete $ENV{$tmv} if (defined($ENV{$tmv}));
+ }}
+
+ # Step 2: Setup the PATH, PATHEXT, switch to the new Perl
+
+ my $pathsep=(win32)? ';' : ':';
+ my $plat_bindir="$TEXDIR/bin/$vars{'this_platform'}";
+ my $perl_bindir="$TEXDIR/tlpkg/tlperl/bin";
+ my $perl_libdir="$TEXDIR/tlpkg/tlperl/lib";
+
+ tllog($::LOG_DEBUG, "Prepending $plat_bindir to PATH\n");
+
+ $ENV{'PATH'}="$plat_bindir" . "$pathsep" . "$ENV{'PATH'}";
+
+ if (win32) {
+ tllog($::LOG_DEBUG, "Prepending $perl_bindir to PATH\n");
+ $ENV{'PATH'}="$perl_bindir" . "$pathsep" . "$ENV{'PATH'}";
+ }
+
+ tllog($::LOG_DEBUG, "\nNew PATH is now:\n");
+ foreach my $dir (split $pathsep, $ENV{'PATH'}) {
+ tllog($::LOG_DEBUG, " $dir\n");
+ }
+ tllog($::LOG_DEBUG, "\n");
+
+ if (win32) {
+ $ENV{'PATHEXT'}=".texlua;" . "$ENV{'PATHEXT'}";
+ $ENV{'TEXBINDIR'}=$TEXDIR . "\\bin\\win32";
+ $ENV{'TEXBINDIR'} =~ s!/!\\!g;
+ $ENV{'PERL5LIB'}="$perl_libdir";
+ }
+
+
+ # Step 4: run the programs
+
+ if (!$opt_portable) {
+ tllog($::LOG_NORMAL, "running mktexlsr $TEXDIR/texmf-dist $TEXDIR/texmf\n");
+ system('mktexlsr', "$TEXDIR/texmf-dist", "$TEXDIR/texmf");
+ }
+
+ # we have to generate the various config file. That could be done with
+ # texconfig generate * but Win32 does not have texconfig. But we have
+ # $localtlpdb and this is simple code, so do it directly, i.e., duplicate
+ # the code from the various generate-*.pl scripts
+ tllog($::LOG_NORMAL, "writing fmtutil.cnf data to $TEXMFSYSVAR/web2c/fmtutil.cnf\n");
+ TeXLive::TLUtils::create_fmtutil($localtlpdb,
+ "$TEXMFSYSVAR/web2c/fmtutil.cnf",
+ "$TEXMFLOCAL/web2c/fmtutil-local.cnf");
+
+ tllog($::LOG_NORMAL, "writing updmap.cfg to $TEXMFSYSVAR/web2c/updmap.cfg\n");
+ TeXLive::TLUtils::create_updmap ($localtlpdb,
+ "$TEXMFSYSVAR/web2c/updmap.cfg",
+ "$TEXMFLOCAL/web2c/updmap-local.cfg");
+
+ tllog($::LOG_NORMAL, "writing language.dat data to $TEXMFSYSVAR/tex/generic/config/language.dat\n");
+ TeXLive::TLUtils::create_language($localtlpdb,
+ "$TEXMFSYSVAR/tex/generic/config/language.dat",
+ "$TEXMFLOCAL/tex/generic/config/language-local.dat");
+
+ tllog($::LOG_NORMAL, "running updmap-sys\n");
+ system('updmap-sys', '--nohash');
+
+ tllog($::LOG_NORMAL, "re-running mktexlsr $TEXMFSYSVAR\n");
+ system('mktexlsr', "$TEXMFSYSVAR");
+
+ # now work through the options if specified at all
+
+ # letter instead of a4
+ if ($vars{'option_letter'}) {
+ tllog($::LOG_NORMAL, "letter option not implemented yet, please wait\n");
+ }
+
+ # all formats option
+ if ($vars{'option_fmt'}) {
+ tllog($::LOG_NORMAL, "pre-generation all format file (fmtutil-sys --all)\n");
+ system('fmtutil-sys','--all');
+ }
+
+ # option_links
+ if ($vars{'option_symlinks'}) {
+ # bin files
+ my @files;
+ mkdirhier $vars{'sys_bin'};
+ if (-w $vars{'sys_bin'}) {
+ tllog($::LOG_NORMAL, "linking binaries to $vars{'sys_bin'}\n");
+ @files = `ls $plat_bindir`;
+ chomp(@files);
+ `cd "$vars{'sys_bin'}" && rm -f @files`;
+ `ln -s "$plat_bindir/"* "$vars{'sys_bin'}"`;
+ } else {
+ tllog($::LOG_NORMAL, "destination of bin symlink $vars{'sys_bin'} not writable, no linking of bin files done!\n");
+ }
+ if ($vars{'option_doc'}) {
+ # info files
+ mkdirhier $vars{'sys_info'};
+ if (-w $vars{'sys_info'}) {
+ tllog($::LOG_NORMAL, "linking info pages to $vars{'sys_info'}\n");
+ @files = `ls "$TEXDIR/texmf/doc/info"`;
+ chomp(@files);
+ `cd "$vars{'sys_info'}" && rm -f @files`;
+ `ln -s "$TEXDIR/texmf/doc/info/"*info* "$vars{'sys_info'}"`;
+ } else {
+ tllog($::LOG_NORMAL, "destination of info symlink $vars{'sys_info'} not writable, no linking of info files done!\n");
+ }
+ # man files
+ mkdirhier $vars{'sys_man'};
+ if (-w $vars{'sys_man'}) {
+ tllog($::LOG_NORMAL, "linking man pages to $vars{'sys_man'}\n");
+ my $foo = `(cd "$TEXDIR/texmf/doc/man" && echo *)`;
+ my @mans = split ' ', $foo;
+ chomp(@mans);
+ foreach my $m (@mans) {
+ my $mandir = "$TEXDIR/texmf/doc/man/$m";
+ next unless -d $mandir;
+ mkdirhier "$vars{'sys_man'}/$m";
+ next unless -w "$vars{'sys_man'}/$m";
+ @files = `ls "$mandir"`;
+ chomp(@files);
+ `cd "$vars{'sys_man'}/$m" && rm -f @files`;
+ `ln -s "$mandir/"* "$vars{'sys_man'}/$m"`;
+ }
+ } else {
+ tllog($::LOG_NORMAL, "destination of man symlink $vars{'sys_man'} not writable, no linking of man files done!\n");
+ }
+ }
+ }
+
+ # old installer:
+ #$config && texconfig-sys init
+ #$config || echo "PLEASE RUN texconfig or texconfig-sys to make new formats."
+}
+
+
+# we have to adjust the texmf.cnf file to the paths set in the configuration!
+sub do_texmf_cnf {
+ open(TMF,"<$vars{'TEXDIR'}/texmf/web2c/texmf.cnf")
+ or die("$vars{'TEXDIR'}/texmf/web2c/texmf.cnf not found: $!\n");
+ my @texmfcnflines = <TMF>;
+ close(TMF);
+ my @newtmf;
+ # we have to find TEXMFLOCAL TEXMFSYSVAR and TEXMFHOME
+ foreach my $line (@texmfcnflines) {
+ if ($line =~ m/^TEXMFLOCAL/) {
+ # by default TEXMFLOCAL = TEXDIR/../texmf-local, if this is the case
+ # we don't have to change anything from the default
+ my $deftmlocal = dirname($vars{'TEXDIR'});
+ $deftmlocal .= "/texmf-local";
+ if ("$vars{'TEXMFLOCAL'}" eq "$deftmlocal") {
+ push @newtmf, $line;
+ } else {
+ push @newtmf, "TEXMFLOCAL = $vars{'TEXMFLOCAL'}\n";
+ }
+ } elsif ($line =~ m/^TEXMFSYSVAR/) {
+ # by default TEXMFSYSVAR = TEXDIR/texmf-var, if this is the case
+ # we don't have to change anything from the default
+ if ("$vars{'TEXMFSYSVAR'}" eq "$vars{'TEXDIR'}/texmf-var") {
+ push @newtmf, $line;
+ } else {
+ push @newtmf, "TEXMFSYSVAR = $vars{'TEXMFSYSVAR'}\n";
+ }
+ } elsif ($line =~ m/^TEXMFHOME/) {
+ # kpse now expands ~ to USERPROFILE, so we don't treat win32 and
+ # unix differently
+ push @newtmf, "TEXMFHOME = $vars{'TEXMFHOME'}\n";
+ } elsif ($line =~ m/^OSFONTDIR/) {
+ if (win32()) {
+ push @newtmf, "OSFONTDIR = \$SystemRoot/fonts//\n";
+ } else {
+ push @newtmf, $line;
+ }
+ } else {
+ push @newtmf, $line;
+ }
+ }
+ open(TMF,">$vars{'TEXDIR'}/texmf/web2c/texmf.cnf")
+ or die("Can't open $vars{'TEXDIR'}/texmf/web2c/texmf.cnf for writing: $!\n");
+ foreach (@newtmf) { print TMF; }
+ close(TMF);
+}
+
+# register texlua handlers etc etc
+sub do_win_registry_magic {
+ # we are called under if (win32()) !!
+ my $texbindir = $vars{'TEXDIR'}."\\bin\\win32";
+ $texbindir =~ s!/!\\!g;
+ add_texbindir_to_path($texbindir);
+ setenv_reg('TEXBINDIR', $texbindir);
+ register_script_type(".texlua", "%TEXBINDIR%/texlua.exe");
+ broadcast_env();
+ update_assocs();
+ register_uninstaller("$vars{'TEXDIR'}") unless $opt_portable;
+}
+
+#
+# do everything to select a scheme
+#
+sub select_scheme {
+ my $s = shift;
+ # set the selected scheme to $s
+ $vars{'selected_scheme'} = $s;
+ # remove the selection of all collections
+ foreach my $entry (keys %vars) {
+ if ($entry=~/^(collection-.*)/) {
+ $vars{"$1"}=0;
+ }
+ }
+ # select the collections belonging to the scheme
+ my $scheme_tlpobj = $tlpdb->get_package($s);
+ if (defined ($scheme_tlpobj)) {
+ $vars{'n_collections_selected'}=0;
+ foreach my $dependent ($scheme_tlpobj->depends) {
+ if ($dependent=~/^(collection-.*)/) {
+ $vars{"$1"}=1;
+ ++$vars{'n_collections_selected'};
+ }
+ }
+ }
+ # for good measure, update the deps
+ calc_depends();
+}
+
+sub update_numbers {
+ $vars{'n_collections_selected'}=0;
+ $vars{'n_systems_available'} = 0;
+ $vars{'n_collections_selected'} = 0;
+ $vars{'n_systems_selected'} = 0;
+ foreach my $key (keys %vars) {
+ if ($key =~ /^binary/) {
+ ++$vars{'n_systems_available'};
+ ++$vars{'n_systems_selected'} if $vars{$key} == 1;
+ }
+ if ($key =~ /^collection-/) {
+ ++$vars{'n_collections_available'};
+ ++$vars{'n_collections_selected'} if $vars{$key} == 1;
+ }
+ }
+}
+
+sub flushlog {
+ my $fh;
+ if (open(LOG,">install-tl.log")) {
+ warn "Writing log file to current working directory!\n";
+ $fh = \*LOG;
+ } else {
+ $fh = \*STDERR;
+ warn "Not creating a log file but flushing messages to stderr:\n";
+ }
+
+ foreach my $l (@::LOGLINES) {
+ print $fh $l;
+ }
+}
+
+__END__
+
+=head1 NAME
+
+install-tl.pl - the TeX Live Cross Platform Installer
+
+=head1 SYNOPSIS
+
+install-tl.pl [OPTION] ...
+
+install-tl.bat [OPTION] ...
+
+=head1 OPTIONS
+
+=over 8
+
+=item B<-gui>
+
+Tries to load the GUI installer using Perl/Tk. If Perl/Tk is not
+available continue with the text mode installer.
+
+=item B<-lang> I<2-letter lang code>
+
+(only for GUI installer) tries to start the installer translated into
+the language specified by the 2-letter language code. Currently supported
+languages are English (en, default), Polish (pl), and German (de).
+
+=item B<-media> I<[CD|DVD|NET]>
+
+Overrides the autodetection of the media.
+
+=item B<-profile> I<profile>
+
+Preloads a TeX Live profile for equal installations on different systems.
+
+=item B<-url> I<url>
+
+Overrides the default URL for network installs. Should start with
+either ftp:// or http://
+
+=item B<-netarchive> I<dir>
+
+Overrides the default settings for netarchive. Should be used with care.
+
+=item B<-diskarchive> I<dir>
+
+Overrides the default settings for diskarchive. Should be used with care.
+
+=item B<-no-cls>
+
+(only for text mode installer) do not clear the screen when entering
+a new menu. For debugging purposes.
+
+=item B<-print-arch>
+
+Print the detected arch-os combination and exit.
+
+=item B<-portable>
+
+Starts the installer for portable use. See below for details.
+
+=item B<-d>, B<-dd>, B<-ddd>
+
+Debugging levels.
+
+=item B<-q>, B<-qq>
+
+B<-q> disables output to the terminal, while B<-qq> also disables output
+to the logfile.
+
+=item B<-help>, B<-h>, B<-?>
+
+print a help message.
+
+=back
+
+=head1 DESCRIPTION
+
+The TeX Live installer works across all supported platforms and allows
+to install TeX Live from various media including the network.
+
+=head1 PORTABLE USE
+
+The TeXLive root directory contains a shell script tl-portable.sh
+and a DOS batch file tl-portable.bat which start up a new shell and
+command prompt in which TeXLive can be run with minimal impact on
+the host system. These files start up install-tl.pl with the
+-portable option for some minimal preparation. Don't use this option
+directly; it makes very specific assumptions about its environment.
+
+=head1 AUTHORS AND COPYRIGHT
+
+This script and its documentation were written for the TeX Live
+distribution (L<http://tug.org/texlive>) and both are licensed under the
+GNU General Public License Version 2 or later.
+
+=cut
+
+### Local Variables:
+### perl-indent-level: 2
+### tab-width: 2
+### indent-tabs-mode: nil
+### End:
+# vim:set tabstop=2 expandtab: #