[tex-live] minor issues with installer

Norbert Preining preining at logic.at
Thu Jul 31 19:09:06 CEST 2008


On Do, 31 Jul 2008, Mojca Miklavec wrote:
> Forget about my stupid idea to catch the error. If possible, it would

Mojca, can you try the attached install-tl with -gui and without X
installed and show me the output?

Best wishes

Norbert

-------------------------------------------------------------------------------
Dr. Norbert Preining <preining at logic.at>        Vienna University of Technology
Debian Developer <preining at debian.org>                         Debian TeX Group
gpg DSA: 0x09C5B094      fp: 14DF 2E6C 0307 BE6D AD76  A9C0 D2BF 4AA3 09C5 B094
-------------------------------------------------------------------------------
LISTOWEL (n.)
The small mat on the bar designed to be more absorbent than the bar,
but not as absorbent as your elbows.
			--- Douglas Adams, The Meaning of Liff
-------------- next part --------------
#!/usr/bin/env perl
# $Id: install-tl 9937 2008-07-31 14:25:26Z preining $
#
# Copyright 2007, 2008 Reinhard Kotucha, Norbert Preining
# This file is licensed under the GNU General Public License version 2
# or any later version.
#
# TODO
# - pod2usage on windows cannot be captured with | more or piped to a file
#   why? I have no idea

my $svnrev = '$Revision: 9937 $';
$svnrev =~ m/: ([0-9]+) /;
$::installerrevision = $1;

# is now taken from 00texlive.config: release, $tlpdb->config_release;
our $texlive_release;

my $localpath;

BEGIN {
  $^W = 1;
  my $me=$0;
  $me=~s!\\!/!g if $^O=~/^MSWin(32|64)$/i;
  if ($me=~m!/!) {
    ($localpath=$me)=~s!(.*)/.*$!$1!;
    # we have to chdir to the Master ...
    chdir($localpath);
  } else {
    $localpath = '.';
  }
  $::installerdir='.';
  # Windows: The installer uses a minimal subset of Perl.  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. The batchfile wrapper takes care of this.
  #if ($^O=~/^MSWin(32|64)$/i) {
  #  @INC="$::installerdir/tlpkg/installer/perllib";
  #}

  # All platforms: add the installer modules
  unshift (@INC, "$::installerdir/tlpkg");
}

use Getopt::Long qw(:config no_autoabbrev);

use TeXLive::TLUtils qw(platform platform_desc
   which getenv win32 unix program_exists info log debug tlwarn ddebug
   get_system_tmpdir member process_logging_options rmtree
   mkdirhier make_var_skeleton make_local_skeleton install_package copy
   install_packages dirname setup_programs welcome welcome_paths);
use TeXLive::TLPOBJ;
use TeXLive::TLPDB;
use TeXLive::TLConfig;
use TeXLive::TLPostActions;
use Pod::Usage;
use Cwd 'abs_path';

if (win32) {
  require TeXLive::TLWinGoo;
  TeXLive::TLWinGoo->import( qw(
    &win_version
    &is_vista
    &admin
    &non_admin
    &reg_country
    &expand_string
    &global_tmpdir
    &get_system_path
    &get_user_path
    &setenv_reg
    &unsetenv_reg
    &add_texbindir_to_path
    &remove_texbindirs_from_path
    &register_extension
    &unregister_extension
    &register_file_type
    &unregister_file_type
    &broadcast_env
    &update_assocs
    &add_desktop_shortcut
    &add_menu_shortcut
    &remove_desktop_shortcut
    &remove_menu_shortcut
    &init_unshortbat
    &create_uninstaller
  ));
}



use strict;

# debugging/logging cmd lines options:
# -q     shut up terminal output but warning messages
# -v     do a bit of debugging to stdout and logfile
#        repeated use increases the value of verbosity
#
@::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;
# 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
#
# The following values are taken from the remote tlpdb using the
#   $tlpdb->option_XXXXX
# settings (i.e., taken from tlpkg/tlpsrc/00texlive-installation.tlpsrc
#
#        '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,
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,
        'src_splitting_supported' => 1,
        'doc_splitting_supported' => 1,
        'selected_scheme' => $default_scheme,
        'from_dvd' => 0,
    );

# option handling
my $opt_from_dvd = "";
my $opt_location = "";
my $opt_profile = "";
my $opt_no_cls=0;
my $opt_nogui = 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";


# if we find a file installation.profile we ask the user whether we should
# continue with the installation
# note, we are in the installer directory!
if (-r "installation.profile") {
  print "ABORTED INSTALLATION FOUND: $localpath/installation.profile!!!\n";
  print "Do you want to continue with the exact same settings as before (y/N): ";
  my $answer = <STDIN>;
  if ($answer =~ m/^y(es)?$/i) {
    $opt_profile = "installation.profile";
  }
}

# first process verbosity/quiet options
process_logging_options();
# now the others
GetOptions(
           "from_dvd" => \$opt_from_dvd,
           "profile=s"=> \$opt_profile,
           "no-cls",
           "gui", \$opt_gui,
           "no-gui", \$opt_nogui,
           "lang=s" => \$::opt_lang,
           "print-arch" => \$opt_arch,
           "portable" => \$opt_portable,
           "non-admin" => \$opt_nonadmin,
           "location|url=s"   => \$opt_location,
           "version" => \$opt_version,
           "help|?" => \$opt_help) or pod2usage(1);

if (win32()) {
  pod2usage(-exitstatus => 0,
            -verbose => 2,
            -noperldoc => 1,
            -output  => \*STDOUT) if $opt_help;
} else {
  pod2usage(-exitstatus => 0, -verbose => 2, -file => $0) if $opt_help;
}

if ($opt_version) {
  print "TeX Live Cross Platform Installer, revision $::installerrevision\n";
  if (-r "release-texlive.txt") {
    # more version info if we can get it.
    print `sed -n '1p;\$p' release-texlive.txt`;
  }
  exit 0;
}

if ($#ARGV >= 0) {
  # we still have arguments left, should only be gui, otherwise die
  if ($ARGV[0] =~ m/^gui$/i) {
    $opt_gui = 1;
  } else {
    die "$0: Extra arguments `@ARGV'; try --help if you need it.\n";
  }
}


if (defined($::opt_lang)) {
  $::lang = $::opt_lang;
}

if ("$opt_profile" ne "") {
  if (-r "$opt_profile") {
    info("Using automated installation using $opt_profile!");
  } else {
    $opt_profile = "";
    info("Profile $opt_profile not readable, continuing in interactive mode!");
  }
}

if ($opt_nonadmin and win32()) { non_admin(); }


# 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;
my $location;

# $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();
my $media;

# a couple of special uses of install-tl:

if ($opt_arch) {
  print platform;
  exit 0;
} elsif ($opt_portable) {
  $::opt_verbosity = -1;
  $::_platform_ = platform();
  $location = getenv('TEXDIR');
  $vars{'TEXDIR'} = $location;
  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{'TEXDIRW'} = getenv('TEXDIRW');
  $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'}";
  mkdirhier "$vars{'TEXMFSYSCONFIG'}";
  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'}");
    # the usual argument for pregenerating all formats doesn't apply
    $vars{'option_fmt'} = 0;
    do_postinst_stuff();
  }
  close($::LOGFILE) if defined($::LOGFILE);
  print TeXLive::TLUtils::welcome;
  exit 0;
}

# continuing with normal install

# initialize the correct platform
platform();
setup_programs ("$::installerdir/tlpkg/installer", "$::_platform_");
$ENV{'WGETRC'}="$::installerdir/tlpkg/installer/wgetrc";

#
# determine from where we do install
#
$location = $opt_location;
$location || ($location = "$::installerdir");
if ($location =~ m!^(http|ftp)://!i) {
  $location =~ s,/(tlpkg|archive)?/*$,,;  # remove any trailing tlpkg or /
  $TeXLiveURL = $location;
  $media = 'NET';
} else {
  # remove leading file:/+ part
  $location =~ s!^file://*!/!i;
  $location = abs_path($location);
  if (-d "$location/$Archive") {
    $media='CD';
  } elsif (-d "$location/texmf/web2c") {
    $media='DVD';
  } else {
    if ($opt_location) {
      # user gave a --location but nothing can be found there, so die
      die "Cannot find installation source at $opt_location!";
    }
    # no --location given, but NET installation
    $TeXLiveURL = $location = TeXLive::TLUtils::give_ctan_mirror();
    $media = 'NET';
  }
}


info("Platform: ", platform, " => \'", platform_desc(platform), "\'\n");
if ($media eq "DVD") {
  info("Distribution: live (uncompressed)\n");
} elsif ($media eq "CD") {
  info("Distribution: inst (compressed)\n");
} elsif ($media eq "NET") {
  info("Distribution: net  (downloading)\n");
  info("Using URL: $TeXLiveURL\n");
} else {
  info("Distribution: $media\n");
}
info("Directory for temporary files: '", $system_tmpdir, "\'\n");
info("Installer directory: '$localpath'\n");

if ($opt_from_dvd and ($media ne "DVD")) {
  print "Not running from DVD; 'from_dvd' option not applicable\n";
  $opt_from_dvd = 0;
}
$vars{'from_dvd'} = $opt_from_dvd;

load_tlpdb();

log("Installer revision: $::installerrevision\n");
log("Database revision: " . $tlpdb->config_revision . "\n");

# correctly set the splitting support
# for DVD we always support splitting
if (($media eq "NET") || ($media eq "CD")) {
  $vars{'src_splitting_supported'} = $tlpdb->config_src_container;
  $vars{'doc_splitting_supported'} = $tlpdb->config_doc_container;
}
$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
      tlwarn("Cannot load Tk, maybe something is missing and\n");
      tlwarn("maybe http://tug.org/texlive/distro.html#perltk can help.\n");
      tlwarn("Error message from loading Tk:\n");
      tlwarn("  $@\n");
      tlwarn("Continuing in text mode...\n");
      $opt_gui = 0;
    }
    eval { my $foo = Tk::MainWindow->new; $foo->destroy; };
    if ($@) {
      tlwarn("Could it be that I cannot create the main windows???\n");
      tlwarn("error message $@\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) {
    debug("run_menu has already done the work ... cleaning up!\n");
    $finished = 1;
  }
  if (!$finished && ($ret != $MENU_INSTALL)) {
    warn("Unknown return value of run_menu: $ret\n");
    exit(3);
  }
} else {
  read_profile("$opt_profile");
}

if (!$finished) {
  # do the actual installation
  # win32: first, remove trailing slash from texdir[w]
  # in case it is the root of a drive
  $vars{'TEXDIR'} =~ s![/\\]$!!;
  $vars{'TEXDIRW'} =~ s![/\\]$!!;
  do_installation();
}

do_cleanup();

exit(0);

###################################################################
#
# FROM HERE ON ONLY SUBROUTINES
# NO VARIABLE DECLARATIONS
#
###################################################################

sub do_installation {
  # do the actual installation
  my $h;
  foreach $h (@::start_install_hook) {
    &$h();
  }
  prepare_installation();
  if (!$vars{'from_dvd'}) {
    calc_depends();
    save_options_into_tlpdb();
    do_install_packages();
  }
  if (win32()) {
    add_texbindir_to_path($vars{'TEXDIR'}.'/bin/win32');
    # setenv_reg('TEXMFSYSVAR', $vars{'TEXMFSYSVAR'}) if $vars{'from_dvd'};
    setenv_reg('TEXMFCNF', $vars{'TEXMFSYSVAR'}.'/web2c') if $vars{'from_dvd'};
    broadcast_env();
    create_uninstaller($vars{'TEXDIR'}, $vars{'TEXDIRW'},
      $vars{'TEXMFSYSVAR'}, $vars{'TEXMFSYSCONFIG'});
  }
  foreach $h (@::start_postinst_hook) {
    &$h();
  }
  do_postinst_stuff();
  $localtlpdb->save unless $vars{'from_dvd'};
  foreach $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));
  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_TEXMFSYSCONFIG $TEXDIR/texmf-config
#   TEXLIVE_INSTALL_TEXMFLOCAL     $tex_prefix/texmf-local
#   TEXLIVE_INSTALL_TEXMFHOME      '$HOME/texmf'

sub set_texlive_default_dirs {
  my $tex_prefix;
  my $texmfsysvar;
  my $texmfsysconfig;
  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{'TEXDIRW'}="$tex_prefix/$texlive_release";

  $texmfsysvar=getenv('TEXLIVE_INSTALL_TEXMFSYSVAR');
  $texmfsysvar||=$vars{'TEXDIRW'} . '/texmf-var';
  $vars{'TEXMFSYSVAR'}=$texmfsysvar;

  $texmfsysconfig=getenv('TEXLIVE_INSTALL_TEXMFSYSCONFIG');
  $texmfsysconfig||=$vars{'TEXDIRW'} . '/texmf-config';
  $vars{'TEXMFSYSCONFIG'}=$texmfsysconfig;

  $texmflocal=getenv('TEXLIVE_INSTALL_TEXMFLOCAL');
  $texmflocal||="$tex_prefix/texmf-local";
  $vars{'TEXMFLOCAL'}=$texmflocal;

  $vars{'TEXDIR'} = $vars{'from_dvd'} ? abs_path($::installerdir) :
    $vars{'TEXDIRW'};

  $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=();
  my $p;
  my $a;

  # 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 and bin-tlpsv.win32, too
  if (grep(/^win32$/, at archs)) {
    $install{"bin-tlperl.win32"} = 1;
    $install{"bin-tlgs.win32"} = 1;
    $install{"bin-tlpsv.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;
    ddebug("initial number of installations: $#pre_selected\n");

    # loop over all the pre_selected and add them
    foreach $p (@pre_selected) {
      ddebug("pre_selected $p\n");
      my $pkg = $tlpdb->get_package($p);
      if (!defined($pkg)) {
        tlwarn("W: $p is mentioned somewhere but not available, disabling it!\n");
        $install{$p} = 0;
        next;
      }
      foreach my $p_dep ($tlpdb->get_package($p)->depends) {
        if ($p_dep =~ m/^(.*)\.ARCH$/) {
          my $foo = "$1";
          foreach $a (@archs) {
            $install{"$foo.$a"} = 1 if defined($tlpdb->get_package("$foo.$a"));
          }
        } elsif ($p_dep =~ m/^(.*)\.win32$/) {
          # a win32 package should *only* be installed if we are installing
          # the win32 arch
          if (grep(/^win32$/, at archs)) {
            $install{$p_dep} = 1;
          }
        } else {
          $install{$p_dep} = 1;
        }
      }
    }

    # check for newly selected packages
    my @post_selected = keys %install;
    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 $p (keys %install) {
    my $tlpobj = $tlpdb->get_package($p);
    if (not(defined($tlpobj))) {
      tlwarn("W: $p should be installed bug cannot be found in texlive.tlpdb!\n");
      tlwarn("W: disabling it (expect this messages a view times!)\n");
      $install{$p} = 0;
      next;
    }
    $size+=$tlpobj->docsize if $vars{'option_doc'};
    $size+=$tlpobj->srcsize if $vars{'option_src'};
    $size+=$tlpobj->runsize;
    foreach $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 = $location;
  info("Loading $master/$TeXLive::TLConfig::InfraLocation/$TeXLive::TLConfig::DatabaseName\n");
  $tlpdb=TeXLive::TLPDB->new(root => "$master");
  if (!defined($tlpdb)) {
    die("Cannot load TeX Live Database from $master");
  }
  # set the defaults to what is specified in the tlpdb
  $vars{'option_doc'} = $tlpdb->option_install_docfiles;
  $vars{'option_src'} = $tlpdb->option_install_srcfiles;
  $vars{'option_fmt'} = $tlpdb->option_create_formats;
  $vars{'option_letter' } = ( $tlpdb->option_paper eq "letter" ? 1 : 0 );
  $vars{'option_symlinks'} = $tlpdb->option_create_symlinks;
  $vars{'sys_bin'} = $tlpdb->option_sys_bin;
  $vars{'sys_man'} = $tlpdb->option_sys_man;
  $vars{'sys_info'} = $tlpdb->option_sys_info;
}

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'};
      }
    }
  }
  if ($vars{"binary_win32"}) {
    $vars{"collection-wintools"} = 1;
    ++$vars{'n_collections_selected'};
  }
}

sub set_install_platform {
  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 updated and reflects only the\n";
  print $fh "# installation profile at installation time.\n";
  print $fh "selected_scheme $vars{selected_scheme}\n";
  foreach my $key (sort 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/;  # includes TEXDIRW
    print $fh "$key $vars{$key}\n" if $key=~/^TEXMFSYSVAR/;
    print $fh "$key $vars{$key}\n" if $key=~/^TEXMFSYSCONFIG/;
    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{$_}; }
  }
  # if a profile contains *only* the selected_scheme setting without
  # any collection, we assume that exactely that scheme should be installed
  my $coldefined = 0;
  foreach my $k (keys %pro) {
    if ($k =~ m/^collection-/) {
      $coldefined = 1;
      last;
    }
  }
  # if at least one collection has been defined return here
  return if $coldefined;
  # since no collections have been defined in the profile, we
  # set those to be installed on which the scheme depends
  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) {
    $vars{"$scheme_content"}=1 if ($scheme_content=~/^collection-/);
  }
}

sub prepare_installation {
  make_var_skeleton "$vars{'TEXMFSYSVAR'}";
  make_local_skeleton "$vars{'TEXMFLOCAL'}";
  mkdirhier "$vars{'TEXMFSYSCONFIG'}";

  if ($vars{'from_dvd'}) {
    $localtlpdb = $tlpdb;
  } else {
    $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,$media,$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 {
  $localtlpdb->option_platform($::_platform_);
  $localtlpdb->option_location($location);
  $localtlpdb->option_paper($vars{'option_letter'} ? "letter" : "a4");
  $localtlpdb->option_create_formats($vars{'option_fmt'} ? "1" : "0");
  $localtlpdb->option_create_symlinks($vars{'option_symlinks'} ? "1" : "0");
  $localtlpdb->option_sys_bin($vars{'sys_bin'});
  $localtlpdb->option_sys_info($vars{'sys_info'});
  $localtlpdb->option_sys_man($vars{'sys_man'});
  $localtlpdb->option_install_docfiles($vars{'option_doc'} ? "1" : "0");
  $localtlpdb->option_install_srcfiles($vars{'option_doc'} ? "1" : "0");
  my @archs;
  foreach (keys %vars) {
    if (m/^binary_(.*)$/ ) {
      if ($vars{$_}) { push @archs, $1; }
    }
  }
  $localtlpdb->option_available_architectures(@archs);
  $localtlpdb->save() unless $vars{'from_dvd'};
}

# 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 $TEXDIRW="$vars{'TEXDIRW'}";
  my $TEXMFSYSVAR="$vars{'TEXMFSYSVAR'}";
  my $TEXMFSYSCONFIG="$vars{'TEXMFSYSCONFIG'}";
  my $TEXMFLOCAL="$vars{'TEXMFLOCAL'}";
  my $tmv;

  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 @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);

  if (defined($ENV{'TEXMFCNF'}) and !$vars{'from_dvd'}) {
    print "WARNING: environment variable TEXMFCNF is set.
You should know what you are doing.
We will remove that for the post install actions, but all further
operations might be disturbed.\n\n";
  }
  foreach $tmv (@TMFVARS0) {
    delete $ENV{$tmv} if (defined($ENV{$tmv}));
  }
  if (!$opt_portable) {
    foreach $tmv (@TMFVARS1) {
      delete $ENV{$tmv} if (defined($ENV{$tmv}));
    }
  }
  $ENV{'TEXMFSYSVAR'} = $vars{'TEXMFSYSVAR'} if $vars{'from_dvd'};

  # Step 2: Setup the PATH, 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";

  debug("Prepending $plat_bindir to PATH\n");

  $ENV{'PATH'}="$plat_bindir" . "$pathsep" . "$ENV{'PATH'}";

  if (win32) {
    debug("Prepending $perl_bindir to PATH\n");
    $ENV{'PATH'}="$perl_bindir" . "$pathsep" . "$ENV{'PATH'}";
  }

  debug("\nNew PATH is now:\n");
  foreach my $dir (split $pathsep, $ENV{'PATH'}) {
    debug("  $dir\n");
  }
  debug("\n");

  if (win32) {
    $ENV{'PERL5LIB'}="$perl_libdir";
  }

  #
  # post install actions
  #

  # (re-)initialize batchfile for uninstalling shortcuts
  if (win32() and !$opt_portable) {
    mkdirhier("$TEXDIRW/tlpkg/installer") if $vars{'from_dvd'};
    init_unshortbat($TEXDIRW);
  }

  foreach my $package (sort keys %install) {
    if ($install{$package} && defined($PostInstall{$package})) {
      info("running post install action for $package\n");
      &{$PostInstall{$package}}($TEXDIR, $TEXDIRW, $TEXMFSYSVAR, $TEXMFLOCAL);
    }
  }
  # $opt_portable: no %install but we still want xetex postinstall
  &{$PostInstall{'xetex'}}($TEXDIR, $TEXDIRW, $TEXMFSYSVAR, $TEXMFLOCAL)
    if $opt_portable;
  update_assocs() if win32();

  # Step 4: run the programs

  if (!$opt_portable and !$vars{'from_dvd'}) {
    info("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
  info("writing fmtutil.cnf data to $TEXMFSYSVAR/web2c/fmtutil.cnf\n");
  my $tlp = $vars{'from_dvd'} ? $tlpdb : $localtlpdb;
  TeXLive::TLUtils::create_fmtutil($tlp, #$localtlpdb,
    "$TEXMFSYSVAR/web2c/fmtutil.cnf",
    "$TEXMFLOCAL/web2c/fmtutil-local.cnf");

  info("writing updmap.cfg to $TEXMFSYSVAR/web2c/updmap.cfg\n");
  TeXLive::TLUtils::create_updmap ($tlp, #$localtlpdb,
    "$TEXMFSYSVAR/web2c/updmap.cfg",
    "$TEXMFLOCAL/web2c/updmap-local.cfg");

  info("writing language.dat data to $TEXMFSYSVAR/tex/generic/config/language.dat\n");
  TeXLive::TLUtils::create_language_dat($tlp, #$localtlpdb,
    "$TEXMFSYSVAR/tex/generic/config/language.dat",
    "$TEXMFLOCAL/tex/generic/config/language-local.dat");

  info("writing language.def data to $TEXMFSYSVAR/tex/generic/config/language.def\n");
  TeXLive::TLUtils::create_language_def($tlp, #$localtlpdb,
    "$TEXMFSYSVAR/tex/generic/config/language.def",
    "$TEXMFLOCAL/tex/generic/config/language-local.def");

  info("running mktexlsr $TEXMFSYSVAR\n");
  system('mktexlsr', "$TEXMFSYSVAR");

  info("running updmap-sys\n");
  # system('updmap-sys', '--nohash');
  log(`updmap-sys --nohash 2>&1`);

  info("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'}) {
    info("Setting default paper size to letter\n");
    if (platform() eq "hppa-hpux") {
      # we didn't get a texlua binary for hppa-hpux, so try texconfig
      system("texconfig", "paper", "letter");
    } else {
      system("texlua", "$TEXDIR/texmf/scripts/texlive/texconf.tlu", "--sys", "--noformat", "paper", "letter");
    }
  }

  # all formats option
  if ($vars{'option_fmt'}) {
    info("pre-generation all format file (fmtutil-sys --all)\n");
    #system('fmtutil-sys','--all');
    # try to capture that output
    log(`fmtutil-sys --all 2>&1`);
  }

  # option_links
  if ($vars{'option_symlinks'}) {
    # bin files
    my @files;
    mkdirhier $vars{'sys_bin'};
    if (-w $vars{'sys_bin'}) {
      info("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 {
      info("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'}) {
        info("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 {
        info("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'}) {
        info("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 {
        info("destination of man symlink $vars{'sys_man'} not writable, no linking of man files done!\n");
      }
    }
  }
}


# 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;
  my @changedtmf;
  # 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";
        push @changedtmf, "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";
        push @changedtmf, "TEXMFSYSVAR = $vars{'TEXMFSYSVAR'}\n";
      }
    } elsif ($line =~ m/^TEXMFSYSCONFIG/) {
      # by default TEXMFSYSCONFIG = TEXDIR/texmf-config, if this is the case
      # we don't have to change anything from the default
      if ("$vars{'TEXMFSYSCONFIG'}" eq "$vars{'TEXDIR'}/texmf-config") {
        push @newtmf, $line;
      } else {
        push @newtmf, "TEXMFSYSCONFIG = $vars{'TEXMFSYSCONFIG'}\n";
        push @changedtmf, "TEXMFSYSCONFIG = $vars{'TEXMFSYSCONFIG'}\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";
      if ("$vars{'TEXMFHOME'}" ne "~/texmf") {
        push @changedtmf, "TEXMFHOME = $vars{'TEXMFHOME'}\n";
      }
    } elsif ($line =~ m/^OSFONTDIR/) {
      if (win32()) {
        push @newtmf, "OSFONTDIR = \$SystemRoot/fonts//\n";
        push @changedtmf, "OSFONTDIR = \$SystemRoot/fonts//\n";
      } else {
        push @newtmf, $line;
      }
    } else {
      push @newtmf, $line;
    }
  }
  my $TMF;
  if (!$vars{'from_dvd'}) {
    $TMF = ">$vars{'TEXDIR'}/texmf.cnf";
    open(TMF, $TMF) || die "open($TMF) failed: $!\n";
    print TMF <<EOF;
% This is the texmf.cnf file which contains only changes from the
% texmf.cnf distributed for the release of year YYYY, which is in
% TLROOT/YYYY/texmf/web2c/texmf.cnf.
%
% Please do NOT change values in this YYYY/texmf/web2c/texmf.cnf file,
% as they may be overwritten by later updates of the kpathsea
% package(s).
%
% Instead, if you want to configure something to a value different from
% the one in texmf/web2c/texmf.cnf, just put the changed value here.
%
EOF
;
    foreach (@changedtmf) { print TMF; }
  } else {
    $TMF = ">$vars{'TEXMFSYSVAR'}/web2c/texmf.cnf";
    open (TMF, $TMF) || die "open($TMF) failed: $!\n";
    foreach (@newtmf) { print TMF; }
  }
  close(TMF) || warn "close($TMF) failed: $!";
}

#
# 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'};
      }
    }
  }
  # we have first set all collection-* keys to zero and than
  # set to 1 only those which are required by the scheme
  # since now scheme asks for collection-wintools we set its vars value
  # to 1 in case we are installing win32 binaries
  if ($vars{"binary_win32"}) {
    $vars{"collection-wintools"} = 1;
    ++$vars{'n_collections_selected'};
  }
  # for good measure, update the deps
  calc_depends();
}

sub update_numbers {
  $vars{'n_collections_available'}=0;
  $vars{'n_collections_selected'} = 0;
  $vars{'n_systems_available'} = 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;
  }
}

sub check_on_lang_collection_installed {
  # we check that at least one lang collection is installed:
  foreach my $c (@collections_lang) {
    return 1 if $vars{"$c"};
  }
  if ($vars{"selected_scheme"} eq "scheme-context") {
    # context
    return 1;
  }
  return 0;
}

sub do_cleanup
{
  # now open the log file and write out the log lines
  # try to open a log file
  # the user could have given the -logfile option in which case all the
  # stuff is already dumped to it and $::LOGFILE defined. So do not
  # redefine it
  if (!defined($::LOGFILE)) {
    if (open(LOGF,">$vars{'TEXDIRW'}/install-tl.log")) {
      $::LOGFILE = \*LOGF;
      foreach my $line(@::LOGLINES) {
        print $::LOGFILE "$line";
      }
    } else {
      warn("Cannot create log file $vars{'TEXDIRW'}/install-tl.log: $!\nNot writing out log lines!\n");
    }
  }

  # remove temporary files from TEXDIR/temp
  if (($media eq "CD") or ($media eq "NET")) {
    debug("Remove temporary downloaded containers!\n");
    rmtree("$vars{'TEXDIRW'}/temp") if (-d "$vars{'TEXDIRW'}/temp");
  }

  # 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);
  #}

  # should not be needed any more
  #dump_vars("$system_tmpdir/texlive.vars");

  # write the profile out
  if ($vars{'from_dvd'}) {
    create_profile("$vars{'TEXDIRW'}/texlive.profile");
    debug("Profile written to $vars{'TEXDIRW'}/texlive.profile\n");
  } else {
    create_profile("$vars{'TEXDIR'}/$InfraLocation/texlive.profile");
    debug("Profile written to $vars{'TEXDIR'}/$InfraLocation/texlive.profile\n");
  }
  # Close log file if present
  close($::LOGFILE) if defined($::LOGFILE);

  #print "Don't forget to set TEXMFSYSVAR to ".$vars{'TEXMFSYSVAR'}."!!!\n"
  #print "Don't forget to set TEXMFCNF to\n  ". $vars{'TEXMFSYSVAR'}."/web2c !!!\n"
  #  if ($vars{'from_dvd'} and !win32());
}

__END__

=head1 NAME

install-tl - the TeX Live Cross Platform Installer

=head1 SYNOPSIS

install-tl [OPTION]...

install-tl.bat [OPTION]...

=head1 OPTIONS

=over 8

=item B<-gui>

If possible, use the GUI installer. This requires the Perl/Tk module
(L<http://tug.org/texlive/distro.html#perltk>; if Perl/Tk is not
available, installation continues in text mode.

=item B<-no-gui>

Force using the text mode installer.

=item B<-lang> I<2-letter lang code>

(only for GUI installer) If possible, start the installer translated into
the language specified by the 2-letter language code. Currently supported
languages: English (en, default), German (de), French (fr), Dutch (nl),
Polish (pl) and Slovenian (sl).

=item B<-location> I<url|path>

Provide an installation source, either a local directory via
C</path/to/directory> or a C<file:/> url, or a network location via
a C<http://> or C<ftp://> url.

If the location is local, the installation type (compressed or live) is
automatically determined, by checking for the presence of a
C<archive> directory relative to the root.  Compressed is
preferred if both are available, since it is faster.  Here's an example
of using a local directory:

  -location /local/TL/repository/copy

If the location is on the network, trailing C</> characters and/or
trailing C</tlpkg> and C</archive> components are ignored.  For example,
you could choose a particular CTAN mirror with something like:

  -location http://ctan.example.org/tex-archive/texlive/tlnet/2008

Of course a proper hostname and its particular top-level CTAN path
have to be specified.  (The list of CTAN mirrors is maintained at
L<http://ctan.org/mirrors>.)

The default is to pick a mirror automatically, using
L<http://mirror.ctan.org>; the chosen mirror is used for the entire
download.  (See L<http://ctan.org> for more about the CTAN mirror
services.)

=item B<-no-cls>

(only for text mode installer) do not clear the screen when entering
a new menu, for debugging purposes.

=item B<-portable>

Start the installer for portable use---but use the C<tl-portable>
scripts instead of this option.  See below for details.

=item B<-non-admin>

Windows: configure for the current user, not for all users

=item B<-print-arch>

Print the detected arch-os combination and exit.

=item B<-profile> I<profile>

Load the I<profile> file for repeated installations on different systems.
A I<profile> contains the values of all necessary variable for the
installation. After normal installation has finished a profile for that
exact installation is written into DEST/tlpkg/texlive.profile. That file
can be used to do the exact same installation on a different computer.

You can also hand-craft such a profile starting from a generated one
by changing some values. Normally a profile has to contain the value 1 for
each collection that should be installed, even if the scheme is specified.
That follows from the logic of the installer that you first select a scheme
and then can change the actual collections being installed.

There is one exception to this: If the profile contains a variable for
B<selected_scheme> and I<NO> collection variable is defined in the profile,
then the collections which the specified scheme requires are installed.
Thus, a simple line C<selected_scheme scheme-medium> together with the
definitions of the paths (TEXDIR, TEXDIRW, TEXMFHOME, TEXMFLOCAL,
TEXMFSYSCONFIG, TEXMFSYSVAR) suffice to install the medium scheme with all
default options.

=item B<-q>

Omit normal informational messages.

=item B<-v>

Include debugging messages; repeat for maximum debugging, as in C<-v
-v>.  (Further repeats are accepted but ignored.)

=item B<-logfile> I<file>

Write both all messages (informational, debugging, warnings) to I<file>,
in addition to standard output or standard error.

If this option is not given, the installer will create a log file
in the root of the writable installation tree,
for example, C</usr/local/texlive/YYYY/install-tl.log> for the I<YYYY>
release.

=item B<--help>, B<-help>, B<-?>

Display this help and exit.

=item B<--version>, B<-version>

Output version information and exit.

=back

As usual, all options can be specified with either C<-> or C<-->, and
arguments can be be separated from their options by either a space or C<=>.

=head1 DESCRIPTION

The TeX Live installer works across all supported platforms and allows
to install TeX Live from various media, including the network.  See
L<http://tug.org/texlive/tlmgr.html> for more.


=head1 PORTABLE USE

The TeX Live root directory contains a shell script C<tl-portable.sh>
and a DOS batch file C<tl-portable.bat> which start up a new shell and
command prompt in which TeX Live can be run with minimal impact on the
host system. These files start up C<install-tl> with the
C<-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: #


More information about the tex-live mailing list