From 37578c7253166e9cfb76bbbde0b48279f5ce7f61 Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Sat, 3 May 2008 10:21:13 +0000 Subject: get rid of tlmgr.tlu, rename tl-package-manger.pl to tlmgr.pl, merge uninstall-tl.pl funcionality, adapt TLWinGoo uninstaller to use it git-svn-id: svn://tug.org/texlive/trunk@7812 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf/scripts/texlive/texconf.tlu | 5 +- Master/texmf/scripts/texlive/tl-package-manager.pl | 868 ---------------- Master/texmf/scripts/texlive/tlmgr.pl | 1086 ++++++++++++++++++++ Master/texmf/scripts/texlive/tlmgr.tlu | 180 ---- Master/texmf/scripts/texlive/uninstall-tl.pl | 155 --- Master/tlpkg/TeXLive/TLWinGoo.pm | 2 +- 6 files changed, 1089 insertions(+), 1207 deletions(-) delete mode 100755 Master/texmf/scripts/texlive/tl-package-manager.pl create mode 100755 Master/texmf/scripts/texlive/tlmgr.pl delete mode 100755 Master/texmf/scripts/texlive/tlmgr.tlu delete mode 100755 Master/texmf/scripts/texlive/uninstall-tl.pl diff --git a/Master/texmf/scripts/texlive/texconf.tlu b/Master/texmf/scripts/texlive/texconf.tlu index 32c6da8726f..83e7a5e1573 100755 --- a/Master/texmf/scripts/texlive/texconf.tlu +++ b/Master/texmf/scripts/texlive/texconf.tlu @@ -53,8 +53,7 @@ end if (options["noformat"]) then noformatopt = true end - - + if (sys) then texmfconfig=kpse.var_value('TEXMFSYSCONFIG') else @@ -570,7 +569,7 @@ if sys and domktexlsr then os.spawn(command) end -if noformat then +if noformatopt then doformat = false end diff --git a/Master/texmf/scripts/texlive/tl-package-manager.pl b/Master/texmf/scripts/texlive/tl-package-manager.pl deleted file mode 100755 index 0978a69a8a7..00000000000 --- a/Master/texmf/scripts/texlive/tl-package-manager.pl +++ /dev/null @@ -1,868 +0,0 @@ -#!/usr/bin/env perl - -# $Id: tl-package-manager.pl 6381 2008-01-23 17:50:54Z preining $ -# -# Copyright 2008 Norbert Preining -# This file is licensed under the GNU General Public License version 2 -# or any later version. -# -# TODO: -# - (idea/problem) every time we re-generate the updmap/fmtutil files -# with generate ... we destroy everything the admin/user might have -# added via --enable or --disable. That is bad. -# What about doing *all* (i.e., at installation time and at update -# time) via enable/disable calls? -# - ordering or collections removal (see below for details) -# - (?) removal does not remove created format files from TEXMFSYSVAR -# - other features: dependency check?, ...? -# - cmd -# default -# sets the options in texlive.tlpdb -# done for location -# change that???????? -# default show location -# default show docfiles -# default show .... -# -# default set location .... -# default set docfiles .... -# -# NOTE: -# We keep the FULL DOCUMENTATION of tlmgr in this file since all options -# are forwarded to tl-package-manager. Therefore the pod documentation -# also mentions "tlmgr" instead of tl-package-manager.pl!! -# -# Please if you add something tl tlmgr.texlua also add documentation here! -# - - -my $Master; - -BEGIN { - $^W = 1; - $Master = `kpsewhich -var-value=SELFAUTOPARENT`; - chomp($Master); - unshift (@INC, "$Master/tlpkg"); -} - -use TeXLive::TLPOBJ; -use TeXLive::TLPDB; -use TeXLive::TLConfig; -use TeXLive::TLMedia; -use TeXLive::TLUtils; -TeXLive::TLUtils->import( qw(kpsewhich member) ); -use Cwd qw/abs_path/; -use Pod::Usage; -use Getopt::Long qw(:config no_autoabbrev pass_through); -#$Getopt::Long::autoabbrev=0; -#$Getopt::Long::pass_through=1; -use strict; - - -# used variables -# the TLMedia from which we install/update -my $tlmediasrc; -# the tlpdb of the install media -my $tlpdb; -# the local tlpdb -my $localtlpdb; -# a hash for saving the options saved into the local tlpdb -my %options; -# the location from where we install -my $location; - -# option handling -my $opt_location; -my $opt_nodepends = 0; -my $opt_help = 0; -my $opt_debug = 0; -my $opt_force = 0; -my $opt_dry = 0; -my $localconf = ""; -my $dest = ""; - -GetOptions("location=s" => \$opt_location, - "netarchive=s" => \$NetArchive, - "diskarchive=s" => \$DiskArchive, - "no-depends" => \$opt_nodepends, - "force" => \$opt_force, - "localcfg=s" => \$localconf, - "dest=s" => \$dest, - "dry-run" => \$opt_dry, - "debug!", "h|help|?" => \$opt_help) or pod2usage(1); - -my $action = shift; -if (!defined($action) && !$opt_help) { - print "missing action\ntry 'tlmgr help' for more information.\n"; - exit 1; -} - -if (defined($action) && ($action =~ m/^help/i)) { - $opt_help = 1; -} - -if ($^O=~/^MSWin(32|64)$/i) { - pod2usage(-exitstatus => 0, -verbose => 2, -noperldoc => 1) if $opt_help; -} else { - pod2usage(-exitstatus => 0, -verbose => 2) if $opt_help; -} - - -if ($opt_debug) { - $::LOGLEVELFILE = $::LOG_DDDEBUG; - $::LOGLEVELTERMINAL = $::LOG_DDDEBUG; -} - -# -# here starts the magic -# -$localtlpdb = TeXLive::TLPDB->new ("root" => "$Master"); -die("cannot find tlpdb!") unless (defined($localtlpdb)); - -# let cmd line options override the settings in localtlpdb -my $loc = $localtlpdb->option_location; -if (defined($loc)) { - $location = $loc; -} -if (defined($opt_location)) { - $location = $opt_location; -} - -# setup the programs, for win32 we need the shipped wget/lzma etc, so we -# pass the location of these files to setup_programs. -setup_programs("$Master/tlpkg/installer", $localtlpdb->option_platform); - -my $ret = 0; - -if ($action =~ m/^generate$/i) { - my $what = shift; - #my $localconf = ""; - #my $dest = ""; - #GetOptions("localcfg=s" => \$localconf, "dest=s" > \$dest,) or pod2usage(1); - if ($what =~ m/^language$/i) { - $dest || ($dest = kpsewhich ("TEXMFSYSVAR") . "/tex/generic/config/language.dat"); - $localconf || ($localconf = kpsewhich ("TEXMFLOCAL") . "/tex/generic/config/language-local.dat"); - tllog ($::LOG_NORMAL, "$0: writing language data to $dest\n"); - TeXLive::TLUtils::create_language ($localtlpdb, $dest, $localconf); - } elsif ($what =~ m/^fmtutil$/i) { - $dest || ($dest = kpsewhich("TEXMFSYSVAR") . "/web2c/fmtutil.cnf"); - $localconf || ($localconf = kpsewhich("TEXMFLOCAL") . "/web2c/fmtutil-local.cnf"); - tllog($::LOG_NORMAL, "writing fmtutil.cnf data to $dest\n"); - TeXLive::TLUtils::create_fmtutil($localtlpdb, $dest, $localconf); - } elsif ($what =~ m/^updmap$/i) { - $dest || ($dest = kpsewhich("TEXMFSYSVAR") . "/web2c/updmap.cfg"); - $localconf || ($localconf = kpsewhich("TEXMFLOCAL") . "/web2c/updmap-local.cfg"); - tllog($::LOG_NORMAL, "$0: writing new updmap.cfg to $dest\n"); - TeXLive::TLUtils::create_updmap ($localtlpdb, $dest, $localconf); - } else { - die "Unknown option for generate: $what"; - } - # should we do some postinst actions? - exit(0); -} elsif ($action =~ m/^arch$/i) { - my $what = shift; - if ($what =~ m/^list$/i) { - # list the available architectures - # initialize the TLMedia from $location - $tlmediasrc = TeXLive::TLMedia->new($location); - my $mediatlpdb = $tlmediasrc->tlpdb; - my @already_installed_arch = $localtlpdb->available_architectures; - print "Available architectures:\n"; - foreach my $a ($mediatlpdb->available_architectures) { - if (member($a,@already_installed_arch)) { - print "(i) $a\n"; - } else { - print " $a\n"; - } - } - print "Already installed architectures are marked with (i)\n"; - print "You can add new architectures with tlmgr arch add arch1 arch2\n"; - exit(0); - } elsif ($what =~ m/^add$/i) { - $tlmediasrc = TeXLive::TLMedia->new($location); - my $mediatlpdb = $tlmediasrc->tlpdb; - my @already_installed_arch = $localtlpdb->available_architectures; - my @available_arch = $mediatlpdb->available_architectures; - my @todoarchs; - foreach my $a (@ARGV) { - if (TeXLive::TLUtils::member($a, @already_installed_arch)) { - print "Arch $a is already installed\n"; - next; - } - if (!TeXLive::TLUtils::member($a, @available_arch)) { - print "Arch $a not available, use 'tlmgr available_archs'!\n"; - next; - } - push @todoarchs, $a; - } - foreach my $pkg ($localtlpdb->list_packages) { - next if ($pkg =~ m/^00texlive/); - my $tlp = $localtlpdb->get_package($pkg); - foreach my $dep ($tlp->depends) { - if ($dep =~ m/^(.*)\.ARCH$/) { - # we have to install something - foreach my $a (@todoarchs) { - if ($opt_dry) { - print "Installing $pkg.$a\n"; - } else { - $ret |= $tlmediasrc->install_package("$pkg.$a", $localtlpdb, $opt_nodepends, 1); - } - } - } - } - } - if (TeXLive::TLUtils::member('win32', @todoarchs)) { - # install the necessary win32 stuff - $ret |= $tlmediasrc->install_package("bin-tlperl.win32", $localtlpdb, $opt_nodepends, 1); - $ret |= $tlmediasrc->install_package("bin-tlgs.win32", $localtlpdb, $opt_nodepends, 1); - } - } else { - die "Unknown option for arch: $what"; - } -} elsif ($action =~ m/^default$/i) { - my $what = shift; - die("default needs at least one argument") unless defined($what); - if ($what =~ m/^location$/i) { - # changes the default location - my $loc = shift; - if ($loc) { - print "Setting default location to $loc!\n"; - $localtlpdb->option_location($loc); - $localtlpdb->save; - } else { - print "Default installation source: ", $localtlpdb->option_location, "\n"; - } - } elsif ($what =~ m/^docfiles$/i) { - # changes the default docfiles - my $loc = shift; - if (defined($loc)) { - print "Defaulting to", ($loc ? "" : " not"), " install documentation files!\n"; - $localtlpdb->option_docfiles($loc); - $localtlpdb->save; - } else { - print "Install documentation files: ", $localtlpdb->option_docfiles, "\n"; - } - } elsif ($what =~ m/^srcfiles$/i) { - # changes the default srcfiles - my $loc = shift; - if (defined($loc)) { - print "Defaulting to", ($loc ? "" : " not"), " install source files!\n"; - $localtlpdb->option_srcfiles($loc); - $localtlpdb->save; - } else { - print "Install source files: ", $localtlpdb->option_srcfiles, "\n"; - } - } elsif ($what =~ m/^formats$/i) { - # changes the default formats - my $loc = shift; - if (defined($loc)) { - print "Defaulting to", ($loc ? "" : " not"), " generate format files on installation!\n"; - $localtlpdb->option_formats($loc); - $localtlpdb->save; - } else { - print "Create formats on installation: ", $localtlpdb->option_formats, "\n"; - } - } elsif ($what =~ m/^show$/i) { - print "Default installation location: ", $localtlpdb->option_location, "\n"; - print "Create formats on installation: ", ($localtlpdb->option_formats ? "yes": "no"), "\n"; - print "Install documentation files: ", ($localtlpdb->option_docfiles ? "yes": "no"), "\n"; - print "Install source files: ", ($localtlpdb->option_srcfiles ? "yes": "no"), "\n"; - } else { - warn "Setting other options currently not supported, please edit texlive.tlpdb!"; - } - exit(0); -} elsif ($action =~ m/^list$/i) { - my $what = shift; - $what || ($what = ""); - $tlmediasrc = TeXLive::TLMedia->new($location); - my @whattolist; - if ($what =~ m/^collection/i) { - @whattolist = $tlmediasrc->tlpdb->collections; - } elsif ($what =~ m/^scheme/i) { - @whattolist = $tlmediasrc->tlpdb->schemes; - } else { - @whattolist = $tlmediasrc->tlpdb->list_packages; - } - foreach (@whattolist) { - if (defined($localtlpdb->get_package($_))) { - print "i "; - } else { - print " "; - } - my $foo = $tlmediasrc->tlpdb->get_package($_)->shortdesc; - print "$_: ", defined($foo) ? $foo : "(shortdesc missing)" , "\n"; - } - exit(0); -} elsif ($action =~ m/^install$/i) { - # initialize the TLMedia from $location - $tlmediasrc = TeXLive::TLMedia->new($location); - foreach my $pkg (@ARGV) { - if ($opt_dry) { - print "Installing $pkg\n"; - } else { - # install the packages and run postinstall actions (that is the 1) - $ret |= $tlmediasrc->install_package($pkg, $localtlpdb, $opt_nodepends, 1); - } - } -} elsif ($action =~ m/^update$/i) { - # initialize the TLMedia from $location - $tlmediasrc = TeXLive::TLMedia->new($location); - my $mediatlpdb = $tlmediasrc->tlpdb; - foreach my $pkg ($localtlpdb->list_packages) { - next if ($pkg =~ m/^00texlive/); - my $tlp = $localtlpdb->get_package($pkg); - my $rev = $tlp->revision; - my $mediatlp = $mediatlpdb->get_package($pkg); - if (!defined($mediatlp)) { - print "$pkg cannot be found in $location\n"; - next; - } - my $mediarev = $mediatlp->revision; - if ($rev < $mediarev) { - if ($opt_dry) { - print "Installing $pkg\n"; - } else { - # first remove the package, then reinstall it - # this way we get rid of useless files - # force the deinstallation since we will reinstall it - $ret |= &remove_package($pkg, $localtlpdb, 1); - $ret |= $tlmediasrc->install_package($pkg, $localtlpdb, $opt_nodepends, 1); - } - } elsif ($rev > $mediarev) { - print "revision in $location is less then local revision, not updating!\n"; - next; - } - } -} elsif ($action =~ m/^(global)?search$/i) { - my $r = shift; - my $ret = ""; - my $tlpdb; - my $searchfile = 0; - if ($r =~ m/^-file$/i) { - $searchfile = 1; - $r = shift; - } - if ($action =~ m/^globalsearch$/i) { - my $tlmediasrc = TeXLive::TLMedia->new($location); - $tlpdb = $tlmediasrc->tlpdb; - } else { - $tlpdb = $localtlpdb; - } - foreach my $pkg ($tlpdb->list_packages) { - if ($searchfile) { - my @ret = grep(m;$r;, $tlpdb->get_package($pkg)->all_files); - if (@ret) { - print "$pkg:\n"; - foreach (@ret) { - print "\t$_\n"; - } - } - } else { - next if ($pkg =~ m/\./); - my $t = $tlpdb->get_package($pkg)->shortdesc; - $t |= ""; - my $lt = $tlpdb->get_package($pkg)->longdesc; - $lt |= ""; - if (($pkg =~ m/$r/) || ($t =~ m/$r/) || ($lt =~ m/$r/)) { - $ret .= " $pkg - $t\n"; - } - } - } - print "$ret"; - exit(0); -} elsif ($action =~ m/^show$/i) { - foreach my $pkg (@ARGV) { - my $tlmediatlpdb; - my $tlp = $localtlpdb->get_package($pkg); - my $installed = 0; - if (!$tlp) { - if (!$tlmediatlpdb) { - my $tlmediasrc = TeXLive::TLMedia->new($location); - $tlmediatlpdb = $tlmediasrc->tlpdb; - } - $tlp = $tlmediatlpdb->get_package($pkg); - } else { - $installed = 1; - } - if ($tlp) { - print "Package: ", $tlp->name, "\n"; - print "Category: ", $tlp->category, "\n"; - print "ShortDesc: ", $tlp->shortdesc, "\n" if ($tlp->shortdesc); - print "LongDesc: ", $tlp->longdesc, "\n" if ($tlp->longdesc); - print "Installed: ", ($installed?"Yes\n":"No\n"); - print "\n"; - } else { - printf STDERR "Cannot find $pkg\n"; - } - } -} elsif ($action =~ m/^remove$/i) { - # we do the following: - # - (not implemented) order collections such that those depending on - # other collections are first removed, and then those which only - # depend on packages. Otherwise - # remove collection-latex collection-latexrecommended - # will not succeed - # - first loop over all cmd line args and consider only the collections - # - for each to be removed collection: - # . check that no other collections/scheme asks for that collection - # . remove the collection - # . remove all dependencies - # - for each normal package not already removed (via the above) - # . check that no collection/scheme still depends on this package - # . remove the package - # - my %already_removed; - my @more_removal; - foreach my $pkg (@ARGV) { - my $tlp = $localtlpdb->get_package($pkg); - next if defined($already_removed{$pkg}); - if (!defined($tlp)) { - print "Package $pkg not present, cannot remove it!\n"; - } else { - # in the first round we only remove collections, nothing else - # but removing collections will remove all dependencies, too - # save the information of which packages have already been removed - # into %already_removed. - if ($tlp->category eq "Collection") { - # for collections we also remove all dependencies which are - # not Collections or Schemes - my $foo; - if ($opt_dry) { - print "Removing $pkg\n"; - # we need to set $foo to something positive otherwise - # the rest will not be run in dry_run mode - $foo = 0x0001; - } else { - $foo = &remove_package($pkg, $localtlpdb, $opt_force); - } - if ($foo) { - # removal was successful, so the return is at least 0x0001 mktexlsr - # remove dependencies, too - $ret |= $foo; - $already_removed{$pkg} = 1; - if (!$opt_nodepends) { - foreach my $d ($tlp->depends) { - my $tlpdd = $localtlpdb->get_package($d); - if (defined($tlpdd)) { - if ($tlpdd->category !~ m/$MetaCategoriesRegexp/) { - if ($opt_dry) { - print "Removing $d\n"; - } else { - $ret |= &remove_package($d, $localtlpdb, $opt_force); - } - $already_removed{$d} = 1; - } - } - } - } - } - } else { - # save all the other packages into the @more_removal list to - # be removed at the second state. Note that if a package has - # already been removed due to a removal of a collection - # it will be marked as such in %already_removed and not tried again - push @more_removal, $pkg; - } - } - } - foreach my $pkg (@more_removal) { - if (!defined($already_removed{$pkg})) { - if ($opt_dry) { - print "Removing $pkg\n"; - } else { - $ret |= &remove_package($pkg, $localtlpdb, $opt_force); - } - } - } - if (!$opt_dry) { - $localtlpdb->save; - } -} else { - die "Unknown action: $action"; -} - -if ($opt_dry) { - # stop here, don't do any postinstall actions - exit(0); -} - -if ($ret & 0x0001) { - print "running mktexlsr\n"; - system("mktexlsr"); -} -my $TEXMFSYSVAR = `kpsewhich -var-value=TEXMFSYSVAR`; -chomp $TEXMFSYSVAR; -my $TEXMFLOCAL = `kpsewhich -var-value=TEXMFLOCAL`; -chomp $TEXMFLOCAL; -if ($ret & 0x0010) { - print "regenerating updmap.cfg\n"; - TeXLive::TLUtils::create_updmap ($localtlpdb, - "$TEXMFSYSVAR/web2c/updmap.cfg", - "$TEXMFLOCAL/web2c/updmap-local.cfg"); - # system("texconfig-sys", "generate", "updmap"); - print "running updmap-sys\n"; - system("updmap-sys"); -} -if ($ret & 0x0100) { - print "regenerating fmtutil.cnf\n"; - TeXLive::TLUtils::create_fmtutil($localtlpdb, - "$TEXMFSYSVAR/web2c/fmtutil.cnf", - "$TEXMFLOCAL/web2c/fmtutil-local.cnf"); - # system("texconfig-sys", "generate", "fmtutil"); - # running fmtutil-sys only in case that at installation time the - # option for building formats was selected - if ($localtlpdb->option_formats) { - print "running fmtutil-sys --missing\n"; - system("fmtutil-sys", "--missing"); - } -} -if ($ret & 0x1000) { - print "regenerating language.dat\n"; - TeXLive::TLUtils::create_language($localtlpdb, - "$TEXMFSYSVAR/tex/generic/config/language.dat", - "$TEXMFLOCAL/tex/generic/config/language-local.dat"); - # system("texconfig-sys", "generate", "language"); - # - # win32 fmtutil needs language.dat WITHOUT full specification - if (TeXLive::TLUtils::win32()) { - print "running fmtutil-sys --byhyphen language.dat\n"; - system("fmtutil-sys", "--byhyphen", "language.dat"); - } else { - print "running fmtutil-sys --byhyphen $TEXMFSYSVAR/tex/generic/config/language.dat\n"; - system("fmtutil-sys", "--byhyphen", "$TEXMFSYSVAR/tex/generic/config/language.dat"); - } -} - -exit(0); - -# -# remove_package removes a single package with all files (including the -# tlpobj files) and the entry from the tlpdb. -# -sub remove_package { - my ($pkg, $localtlpdb, $force) = @_; - my $tlp = $localtlpdb->get_package($pkg); - my $ret = 0; - if (!defined($tlp)) { - print "Package $pkg not present, cannot remove it!\n"; - } else { - if (!$force) { - # do some checking - my @needed = $localtlpdb->needed_by($pkg); - if (@needed) { - print "Not removing $pkg, is referenced in @needed!\n"; - return $ret; - } - } - print "remove package $pkg\n"; - # we have to chdir to $localtlpdb->root - my $Master = $localtlpdb->root; - chdir ($Master) || die "chdir($Master) failed: $!"; - my @files = $tlp->all_files; - # also remove the .tlpobj file - push @files, "tlpkg/tlpobj/$pkg.tlpobj"; - # and the ones from src/doc splitting - if (-r "tlpkg/tlpobj/$pkg.src.tlpobj") { - push @files, "tlpkg/tlpobj/$pkg.src.tlpobj"; - } - if (-r "tlpkg/tlpobj/$pkg.doc.tlpobj") { - push @files, "tlpkg/tlpobj/$pkg.doc.tlpobj"; - } - my @removals = &removed_dirs (@files); - foreach my $entry (@files) { - unlink $entry; - } - foreach my $entry (@removals) { - rmdir $entry; - } - $localtlpdb->remove_package($pkg); - $ret |= 0x0001; # call mktexlsr - foreach my $e ($tlp->executes) { - if ($e =~ m/^add/) { - $ret |= 0x0010; - } elsif ($e =~ m/^BuildFormat/) { - $ret |= 0x0100; - } elsif ($e =~ m/^BuildLanguageDat/) { - $ret |= 0x1000; - } else { - warn("Unknown execute $e in $pkg"); - } - } - # remove those bin dependencies .ARCH - foreach my $d ($tlp->depends) { - if ($d eq "$pkg.ARCH") { - foreach my $a ($localtlpdb->available_architectures) { - $ret |= &remove_package("$pkg.$a", $localtlpdb, $force); - } - } - } - # should we save at each removal??? - # advantage: the tlpdb actually reflects what is installed - # disadvantage: removing a collection calls the save routine several times - # still I consider it better that the tlpdb is in a consistent state - $localtlpdb->save; - } - return $ret; -} - - -# -# return all the directories from which all content will be removed -# -# idea: -# - create a hashes by_dir listing all files that should be removed -# by directory, i.e., key = dir, value is list of files -# - for each of the dirs (keys of by_dir and ordered deepest first) -# check that all actually contained files are removed -# and all the contained dirs are in the removal list. If this is the -# case put that directory into the removal list -# - return this removal list -# -sub removed_dirs -{ - my (@files) = @_; - my %removed_dirs; - my %by_dir; - - # construct hash of all directories mentioned, values are lists of the - # files/dirs in that directory. - for my $f (@files) { - my $abs_f = abs_path ($f); - if (!$abs_f) { - warn ("oops, no abs_path($f) from " . `pwd`); - next; - } - (my $d = $abs_f) =~ s,/[^/]*$,,; - my @a = exists $by_dir{$d} ? @{$by_dir{$d}} : (); - push (@a, $abs_f); - $by_dir{$d} = \@a; - } - - # for each of our directories, see if we are removing everything in - # the directory. if so, return the directory; else return the - # individual files. - for my $d (reverse sort keys %by_dir) { - opendir (DIR, $d) || die "opendir($d) failed: $!"; - my @dirents = readdir (DIR); - closedir (DIR) || warn "closedir($d) failed: $!"; - - # initialize test hash with all the files we saw in this dir. - # (These idioms are due to "Finding Elements in One Array and Not - # Another" in the Perl Cookbook.) - my %seen; - my @rmfiles = @{$by_dir{$d}}; - @seen{@rmfiles} = (); - - # see if everything is the same. - my $cleandir = 1; - for my $dirent (@dirents) { - next if $dirent =~ /^\.(\.|svn)?$/; # ignore . .. .svn - my $item = "$d/$dirent"; # prepend directory for comparison - if ( - ((-d $item) && (defined($removed_dirs{$item}))) - || - (exists $seen{$item}) - ) { - # do nothing - } else { - $cleandir = 0; - last; - } - } - if ($cleandir) { - $removed_dirs{$d} = 1; - } - } - return keys %removed_dirs; -} - -__END__ - -=head1 NAME - -tlmgr - the TeX Live Manager - -=head1 SYNOPSIS - -tlmgr ACTION [OPTIONS] ... - -=head1 ACTION - -=over 8 - -=item B - -Gives this help page. - -=item B - -Install all packages given on the cmdline. By default this installs all -dependencies, too. See below for the option B<-no-depends>. - -=item B - -Update all packages if newer ones are available - -=item B - -Remove all packages given on the cmdline. Removing a collection will -remove all dependencies, too, unless with option B<-no-depends>. - -Removing a package which is referenced as a dependency in another -collection or scheme will not succeed unless the B<-force> option is given. - -=item B - -=item B [C]> - -The first form shows the default settings as saved in the TeX Live Database. - -In the second form if the C is missing the setting is showed, while -with C present the setting is set to C. - -Possible values for C are: C (default installation source), -C (create formats at installation time), -C (install documentation files), -C (install source files). - -=item B - -=item B - -=item B<[xdvi|dvips|pdftex|dvipdfm|dvipdfmx] paper [help|papersize]> - -Configures the system wide paper settings, either for all programs in -one go, or for the given program on the command line. - -=item B - -Prints the list of arch-os available at the default install location. - -=item B - -Adds binaries for the given architectures to the installtion. - -=item B - -Search the names, short and long descriptions of all locally installed packages -for the given argument (interpreted as regexp). - -With the B<-file> argument searches for files containing C somewhere -in the path, and returning each package with the respective hit. - -=item B - -Search the names, short and long descriptions of all packages available on -the install media. - -With the B<-file> argument searches for files containing C somewhere -in the path, and returning each package with the respective hit. - -=item B - -Shows for each given package the name, category, installation status, -short and long description. Does search in the remote installation -source for finding the package if it is not installed. - - -=item B - -Without argument lists all packages available at the default install -location, prefixing those already installed with "i ". - -With arguments lists only collections or schemes. - -=item B - -Uninstalls the TeX Live installation. - -(This options is implemented in the texlua script and uninstall-tl.pl) - - -=item B - -=item B - -=item B - -Generate language.dat, fmtutil.cnf, and updmap.cfg from a TLPDB and local -additions - -B - -=over 16 - -=item C<-dest> I - -specifies the output file (defaults to the respective location in TEXMFSYSVAR). - -=item C<-localcfg> I - -specifies the (optional) local additions (defaults to the respective location -in TEXMFSYSVAR). - -=back - - -=back - -=head1 OPTIONS - -=over 8 - -=item B<-location> I - -Overrides the location as found in the tlpdb of the installation. Specifies -the location from which packages should be installed or updated. - -=item B<-no-depends> - -Do not install dependencies. If this option is not given installing -a package will check that all dependencies of this package are fulfilled. - -=item B<-force> - -When removing a package or collection would invalidate a dependency -of another collection/scheme, the package will not be removed and -a warning issued. With this options the package will be removed -unconditionally. Use with care. - -=item B<-dry-run> - -For installation and removal of packages, this options enables the chicken -mode, i.e., nothing is actually installed but the actions to be performed -are written to the terminal. - -Note that for all other type of options but package installation and removal -this options does B work! - -=item B<-netarchive> I - -Overrides the default settings for netarchive. Should be used with care. - -=item B<-diskarchive> I - -Overrides the default settings for diskarchive. Should be used with care. - -=back - -The standard options C<-help/-h/-?> and C<-debug> are also accepted. - -=head1 DESCRIPTION - -The B manages an existing TeX Live installation. - -=head1 AUTHORS AND COPYRIGHT - -This script and its documentation were written for the TeX Live -distribution (L) 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: # diff --git a/Master/texmf/scripts/texlive/tlmgr.pl b/Master/texmf/scripts/texlive/tlmgr.pl new file mode 100755 index 00000000000..dc1413d3c93 --- /dev/null +++ b/Master/texmf/scripts/texlive/tlmgr.pl @@ -0,0 +1,1086 @@ +#!/usr/bin/env perl + +# $Id: tlmgr.pl 6381 2008-01-23 17:50:54Z preining $ +# +# Copyright 2008 Norbert Preining +# This file is licensed under the GNU General Public License version 2 +# or any later version. +# +# TODO: +# - (idea/problem) every time we re-generate the updmap/fmtutil files +# with generate ... we destroy everything the admin/user might have +# added via --enable or --disable. That is bad. +# What about doing *all* (i.e., at installation time and at update +# time) via enable/disable calls? +# - ordering or collections removal (see below for details) +# - (?) removal does not remove created format files from TEXMFSYSVAR +# - other features: dependency check?, ...? +# - cmd +# default +# sets the options in texlive.tlpdb +# done for location +# change that???????? +# default show location +# default show docfiles +# default show .... +# +# default set location .... +# default set docfiles .... +# + + +my $Master; + +BEGIN { + $^W = 1; + $Master = `kpsewhich -var-value=SELFAUTOPARENT`; + chomp($Master); + unshift (@INC, "$Master/tlpkg"); +} + +use TeXLive::TLPOBJ; +use TeXLive::TLPDB; +use TeXLive::TLConfig; +use TeXLive::TLMedia; +use TeXLive::TLUtils; +use TeXLive::TLWinGoo; +TeXLive::TLUtils->import( qw(kpsewhich member win32) ); +use Cwd qw/abs_path/; +use Pod::Usage; +use Getopt::Long qw(:config no_autoabbrev require_order pass_through); +use strict; + +# used variables +# the TLMedia from which we install/update +my $tlmediasrc; +# the tlpdb of the install media +my $tlpdb; +# the local tlpdb +my $localtlpdb; +# a hash for saving the options saved into the local tlpdb +my %options; +# the location from where we install +my $location; + +# option handling +my $opt_location; +my $opt_help = 0; +my $opt_debug = 0; + +GetOptions("location=s" => \$opt_location, + "netarchive=s" => \$NetArchive, + "diskarchive=s" => \$DiskArchive, + "debug!", "h|help|?" => \$opt_help) or pod2usage(1); + +my $action = shift; +if (!defined($action) && !$opt_help) { + print "missing action\ntry 'tlmgr help' for more information.\n"; + exit 1; +} + +if (defined($action) && ($action =~ m/^help/i)) { + $opt_help = 1; +} + +if ($^O=~/^MSWin(32|64)$/i) { + pod2usage(-exitstatus => 0, -verbose => 2, -noperldoc => 1) if $opt_help; +} else { + pod2usage(-exitstatus => 0, -verbose => 2) if $opt_help; +} + + +if ($opt_debug) { + $::LOGLEVELFILE = $::LOG_DDDEBUG; + $::LOGLEVELTERMINAL = $::LOG_DDDEBUG; +} + +my $ret = 0; + +if ($action =~ m/^generate$/i) { + $ret = action_generate(); + # should we do postinstall stuff? + exit(0); +} elsif ($action =~ m/^arch$/i) { + $ret = action_arch(); +} elsif ($action =~ m/^default$/i) { + $ret = action_default(); + # should we do postinstall stuff? + exit(0); +} elsif ($action =~ m/^list$/i) { + $ret = action_list(); + # should we do postinstall stuff? + exit(0); +} elsif ($action =~ m/^install$/i) { + $ret = action_install(); +} elsif ($action =~ m/^update$/i) { + $ret = action_update(); +} elsif ($action =~ m/^(global)?search$/i) { + $ret = action_search($action); + exit(0); +} elsif ($action =~ m/^show$/i) { + $ret = action_show(); + exit(0); +} elsif ($action =~ m/^remove$/i) { + $ret = action_remove(); +} elsif (($action eq "paper") || ($action eq "dvips") || ($action eq "xdvi") || + ($action eq "pdftex") || ($action eq "dvipdfm") || + ($action eq "dvipdfmx")) { + my $TEXMFMAIN = `kpsewhich -var-value=TEXMFMAIN`; + chomp $TEXMFMAIN; + system("texlua", "$TEXMFMAIN/scripts/texlive/texconf.tlu", "--prog", "tlmgr", "--sys", $action, @ARGV); + $ret = 0; +} elsif ($action =~ m/^uninstall$/i) { + $ret = action_uninstall(); + exit(0); +} elsif ($action =~ m/^uninstallwin32$/i) { + $ret = action_uninstall_win32(); + exit(0); +} else { + die "Unknown action: $action"; +} + + +if ($ret & 0x0001) { + print "running mktexlsr\n"; + system("mktexlsr"); +} +my $TEXMFSYSVAR = `kpsewhich -var-value=TEXMFSYSVAR`; +chomp $TEXMFSYSVAR; +my $TEXMFLOCAL = `kpsewhich -var-value=TEXMFLOCAL`; +chomp $TEXMFLOCAL; +if ($ret & 0x0010) { + print "regenerating updmap.cfg\n"; + TeXLive::TLUtils::create_updmap ($localtlpdb, + "$TEXMFSYSVAR/web2c/updmap.cfg", + "$TEXMFLOCAL/web2c/updmap-local.cfg"); + # system("texconfig-sys", "generate", "updmap"); + print "running updmap-sys\n"; + system("updmap-sys"); +} +if ($ret & 0x0100) { + print "regenerating fmtutil.cnf\n"; + TeXLive::TLUtils::create_fmtutil($localtlpdb, + "$TEXMFSYSVAR/web2c/fmtutil.cnf", + "$TEXMFLOCAL/web2c/fmtutil-local.cnf"); + # system("texconfig-sys", "generate", "fmtutil"); + # running fmtutil-sys only in case that at installation time the + # option for building formats was selected + if ($localtlpdb->option_formats) { + print "running fmtutil-sys --missing\n"; + system("fmtutil-sys", "--missing"); + } +} +if ($ret & 0x1000) { + print "regenerating language.dat\n"; + TeXLive::TLUtils::create_language($localtlpdb, + "$TEXMFSYSVAR/tex/generic/config/language.dat", + "$TEXMFLOCAL/tex/generic/config/language-local.dat"); + # system("texconfig-sys", "generate", "language"); + # + # win32 fmtutil needs language.dat WITHOUT full specification + if (TeXLive::TLUtils::win32()) { + print "running fmtutil-sys --byhyphen language.dat\n"; + system("fmtutil-sys", "--byhyphen", "language.dat"); + } else { + print "running fmtutil-sys --byhyphen $TEXMFSYSVAR/tex/generic/config/language.dat\n"; + system("fmtutil-sys", "--byhyphen", "$TEXMFSYSVAR/tex/generic/config/language.dat"); + } +} + +exit(0); + +# +# remove_package removes a single package with all files (including the +# tlpobj files) and the entry from the tlpdb. +# +sub remove_package { + my ($pkg, $localtlpdb, $force) = @_; + my $tlp = $localtlpdb->get_package($pkg); + my $ret = 0; + if (!defined($tlp)) { + print "Package $pkg not present, cannot remove it!\n"; + } else { + if (!$force) { + # do some checking + my @needed = $localtlpdb->needed_by($pkg); + if (@needed) { + print "Not removing $pkg, is referenced in @needed!\n"; + return $ret; + } + } + print "remove package $pkg\n"; + # we have to chdir to $localtlpdb->root + my $Master = $localtlpdb->root; + chdir ($Master) || die "chdir($Master) failed: $!"; + my @files = $tlp->all_files; + # also remove the .tlpobj file + push @files, "tlpkg/tlpobj/$pkg.tlpobj"; + # and the ones from src/doc splitting + if (-r "tlpkg/tlpobj/$pkg.src.tlpobj") { + push @files, "tlpkg/tlpobj/$pkg.src.tlpobj"; + } + if (-r "tlpkg/tlpobj/$pkg.doc.tlpobj") { + push @files, "tlpkg/tlpobj/$pkg.doc.tlpobj"; + } + my @removals = &removed_dirs (@files); + foreach my $entry (@files) { + unlink $entry; + } + foreach my $entry (@removals) { + rmdir $entry; + } + $localtlpdb->remove_package($pkg); + $ret |= 0x0001; # call mktexlsr + foreach my $e ($tlp->executes) { + if ($e =~ m/^add/) { + $ret |= 0x0010; + } elsif ($e =~ m/^BuildFormat/) { + $ret |= 0x0100; + } elsif ($e =~ m/^BuildLanguageDat/) { + $ret |= 0x1000; + } else { + warn("Unknown execute $e in $pkg"); + } + } + # remove those bin dependencies .ARCH + foreach my $d ($tlp->depends) { + if ($d eq "$pkg.ARCH") { + foreach my $a ($localtlpdb->available_architectures) { + $ret |= &remove_package("$pkg.$a", $localtlpdb, $force); + } + } + } + # should we save at each removal??? + # advantage: the tlpdb actually reflects what is installed + # disadvantage: removing a collection calls the save routine several times + # still I consider it better that the tlpdb is in a consistent state + $localtlpdb->save; + } + return $ret; +} + +sub action_remove { + # we do the following: + # - (not implemented) order collections such that those depending on + # other collections are first removed, and then those which only + # depend on packages. Otherwise + # remove collection-latex collection-latexrecommended + # will not succeed + # - first loop over all cmd line args and consider only the collections + # - for each to be removed collection: + # . check that no other collections/scheme asks for that collection + # . remove the collection + # . remove all dependencies + # - for each normal package not already removed (via the above) + # . check that no collection/scheme still depends on this package + # . remove the package + # + my $ret = 0; + my $opt_nodepends = 0; + my $opt_force = 0; + my $opt_dry = 0; + Getopt::Long::Configure(qw(no_pass_through)); + GetOptions("no-depends" => \$opt_nodepends, + "force" => \$opt_force, + "dry-run" => \$opt_dry) or pod2usage(1); + my %already_removed; + my @more_removal; + init_local_db(); + foreach my $pkg (@ARGV) { + my $tlp = $localtlpdb->get_package($pkg); + next if defined($already_removed{$pkg}); + if (!defined($tlp)) { + print "Package $pkg not present, cannot remove it!\n"; + } else { + # in the first round we only remove collections, nothing else + # but removing collections will remove all dependencies, too + # save the information of which packages have already been removed + # into %already_removed. + if ($tlp->category eq "Collection") { + # for collections we also remove all dependencies which are + # not Collections or Schemes + my $foo; + if ($opt_dry) { + print "Removing $pkg\n"; + # we need to set $foo to something positive otherwise + # the rest will not be run in dry_run mode + $foo = 0x0001; + } else { + $foo = &remove_package($pkg, $localtlpdb, $opt_force); + } + if ($foo) { + # removal was successful, so the return is at least 0x0001 mktexlsr + # remove dependencies, too + $ret |= $foo; + $already_removed{$pkg} = 1; + if (!$opt_nodepends) { + foreach my $d ($tlp->depends) { + my $tlpdd = $localtlpdb->get_package($d); + if (defined($tlpdd)) { + if ($tlpdd->category !~ m/$MetaCategoriesRegexp/) { + if ($opt_dry) { + print "Removing $d\n"; + } else { + $ret |= &remove_package($d, $localtlpdb, $opt_force); + } + $already_removed{$d} = 1; + } + } + } + } + } + } else { + # save all the other packages into the @more_removal list to + # be removed at the second state. Note that if a package has + # already been removed due to a removal of a collection + # it will be marked as such in %already_removed and not tried again + push @more_removal, $pkg; + } + } + } + foreach my $pkg (@more_removal) { + if (!defined($already_removed{$pkg})) { + if ($opt_dry) { + print "Removing $pkg\n"; + } else { + $ret |= &remove_package($pkg, $localtlpdb, $opt_force); + } + } + } + if ($opt_dry) { + # stop here, don't do any postinstall actions + return(0); + } else { + $localtlpdb->save; + return($ret); + } +} + +sub action_show { + init_local_db(); + foreach my $pkg (@ARGV) { + my $tlmediatlpdb; + my $tlp = $localtlpdb->get_package($pkg); + my $installed = 0; + if (!$tlp) { + if (!$tlmediatlpdb) { + my $tlmediasrc = TeXLive::TLMedia->new($location); + $tlmediatlpdb = $tlmediasrc->tlpdb; + } + $tlp = $tlmediatlpdb->get_package($pkg); + } else { + $installed = 1; + } + if ($tlp) { + print "Package: ", $tlp->name, "\n"; + print "Category: ", $tlp->category, "\n"; + print "ShortDesc: ", $tlp->shortdesc, "\n" if ($tlp->shortdesc); + print "LongDesc: ", $tlp->longdesc, "\n" if ($tlp->longdesc); + print "Installed: ", ($installed?"Yes\n":"No\n"); + print "\n"; + } else { + printf STDERR "Cannot find $pkg\n"; + } + } + return(0); +} + +sub action_search { + my ($action) = shift; + my $r = shift @ARGV; + my $ret = ""; + my $tlpdb; + my $searchfile = 0; + init_local_db(); + if ($r =~ m/^-file$/i) { + $searchfile = 1; + $r = shift @ARGV; + } + if ($action =~ m/^globalsearch$/i) { + my $tlmediasrc = TeXLive::TLMedia->new($location); + $tlpdb = $tlmediasrc->tlpdb; + } else { + $tlpdb = $localtlpdb; + } + foreach my $pkg ($tlpdb->list_packages) { + if ($searchfile) { + my @ret = grep(m;$r;, $tlpdb->get_package($pkg)->all_files); + if (@ret) { + print "$pkg:\n"; + foreach (@ret) { + print "\t$_\n"; + } + } + } else { + next if ($pkg =~ m/\./); + my $t = $tlpdb->get_package($pkg)->shortdesc; + $t |= ""; + my $lt = $tlpdb->get_package($pkg)->longdesc; + $lt |= ""; + if (($pkg =~ m/$r/) || ($t =~ m/$r/) || ($lt =~ m/$r/)) { + $ret .= " $pkg - $t\n"; + } + } + } + print "$ret"; + return(0); +} + +sub action_update { + init_local_db(); + # initialize the TLMedia from $location + my $opt_nodepends = 0; + my $opt_force = 0; + my $opt_dry = 0; + Getopt::Long::Configure(qw(no_pass_through)); + GetOptions("no-depends" => \$opt_nodepends, + "force" => \$opt_force, + "dry-run" => \$opt_dry) or pod2usage(1); + my $ret = 0; + $tlmediasrc = TeXLive::TLMedia->new($location); + my $mediatlpdb = $tlmediasrc->tlpdb; + foreach my $pkg ($localtlpdb->list_packages) { + next if ($pkg =~ m/^00texlive/); + my $tlp = $localtlpdb->get_package($pkg); + my $rev = $tlp->revision; + my $mediatlp = $mediatlpdb->get_package($pkg); + if (!defined($mediatlp)) { + print "$pkg cannot be found in $location\n"; + next; + } + my $mediarev = $mediatlp->revision; + if ($rev < $mediarev) { + if ($opt_dry) { + print "Installing $pkg\n"; + } else { + # first remove the package, then reinstall it + # this way we get rid of useless files + # force the deinstallation since we will reinstall it + $ret |= &remove_package($pkg, $localtlpdb, 1); + $ret |= $tlmediasrc->install_package($pkg, $localtlpdb, $opt_nodepends, 1); + } + } elsif ($rev > $mediarev) { + print "revision in $location is less then local revision, not updating!\n"; + next; + } + } + return($ret); +} + +sub action_install { + init_local_db(); + # initialize the TLMedia from $location + my $opt_nodepends = 0; + my $opt_force = 0; + my $opt_dry = 0; + Getopt::Long::Configure(qw(no_pass_through)); + GetOptions("no-depends" => \$opt_nodepends, + "force" => \$opt_force, + "dry-run" => \$opt_dry) or pod2usage(1); + my $ret = 0; + $tlmediasrc = TeXLive::TLMedia->new($location); + foreach my $pkg (@ARGV) { + if ($opt_dry) { + print "Installing $pkg\n"; + } else { + # install the packages and run postinstall actions (that is the 1) + $ret |= $tlmediasrc->install_package($pkg, $localtlpdb, $opt_nodepends, 1); + } + } + if ($opt_dry) { + # stop here, don't do any postinstall actions + return(0); + } + return($ret); +} + +sub action_list { + init_local_db(); + my $what = shift @ARGV; + $what || ($what = ""); + $tlmediasrc = TeXLive::TLMedia->new($location); + my @whattolist; + if ($what =~ m/^collection/i) { + @whattolist = $tlmediasrc->tlpdb->collections; + } elsif ($what =~ m/^scheme/i) { + @whattolist = $tlmediasrc->tlpdb->schemes; + } else { + @whattolist = $tlmediasrc->tlpdb->list_packages; + } + foreach (@whattolist) { + if (defined($localtlpdb->get_package($_))) { + print "i "; + } else { + print " "; + } + my $foo = $tlmediasrc->tlpdb->get_package($_)->shortdesc; + print "$_: ", defined($foo) ? $foo : "(shortdesc missing)" , "\n"; + } + return(0); +} + +sub action_default { + my $what = shift @ARGV; + die("default needs at least one argument") unless defined($what); + init_local_db(); + if ($what =~ m/^location$/i) { + # changes the default location + my $loc = shift @ARGV; + if ($loc) { + print "Setting default location to $loc!\n"; + $localtlpdb->option_location($loc); + $localtlpdb->save; + } else { + print "Default installation source: ", $localtlpdb->option_location, "\n"; + } + } elsif ($what =~ m/^docfiles$/i) { + # changes the default docfiles + my $loc = shift @ARGV; + if (defined($loc)) { + print "Defaulting to", ($loc ? "" : " not"), " install documentation files!\n"; + $localtlpdb->option_docfiles($loc); + $localtlpdb->save; + } else { + print "Install documentation files: ", $localtlpdb->option_docfiles, "\n"; + } + } elsif ($what =~ m/^srcfiles$/i) { + # changes the default srcfiles + my $loc = shift @ARGV; + if (defined($loc)) { + print "Defaulting to", ($loc ? "" : " not"), " install source files!\n"; + $localtlpdb->option_srcfiles($loc); + $localtlpdb->save; + } else { + print "Install source files: ", $localtlpdb->option_srcfiles, "\n"; + } + } elsif ($what =~ m/^formats$/i) { + # changes the default formats + my $loc = shift @ARGV; + if (defined($loc)) { + print "Defaulting to", ($loc ? "" : " not"), " generate format files on installation!\n"; + $localtlpdb->option_formats($loc); + $localtlpdb->save; + } else { + print "Create formats on installation: ", $localtlpdb->option_formats, "\n"; + } + } elsif ($what =~ m/^show$/i) { + print "Default installation location: ", $localtlpdb->option_location, "\n"; + print "Create formats on installation: ", ($localtlpdb->option_formats ? "yes": "no"), "\n"; + print "Install documentation files: ", ($localtlpdb->option_docfiles ? "yes": "no"), "\n"; + print "Install source files: ", ($localtlpdb->option_srcfiles ? "yes": "no"), "\n"; + } else { + warn "Setting other options currently not supported, please edit texlive.tlpdb!"; + } + return(0); +} + +sub action_arch { + my $what = shift @ARGV; + my $ret = 0; + my $opt_nodepends = 0; + my $opt_force = 0; + my $opt_dry = 0; + Getopt::Long::Configure(qw(no_pass_through)); + GetOptions("no-depends" => \$opt_nodepends, + "force" => \$opt_force, + "dry-run" => \$opt_dry) or pod2usage(1); + init_local_db(); + if ($what =~ m/^list$/i) { + # list the available architectures + # initialize the TLMedia from $location + $tlmediasrc = TeXLive::TLMedia->new($location); + my $mediatlpdb = $tlmediasrc->tlpdb; + my @already_installed_arch = $localtlpdb->available_architectures; + print "Available architectures:\n"; + foreach my $a ($mediatlpdb->available_architectures) { + if (member($a,@already_installed_arch)) { + print "(i) $a\n"; + } else { + print " $a\n"; + } + } + print "Already installed architectures are marked with (i)\n"; + print "You can add new architectures with tlmgr arch add arch1 arch2\n"; + exit(0); + } elsif ($what =~ m/^add$/i) { + $tlmediasrc = TeXLive::TLMedia->new($location); + my $mediatlpdb = $tlmediasrc->tlpdb; + my @already_installed_arch = $localtlpdb->available_architectures; + my @available_arch = $mediatlpdb->available_architectures; + my @todoarchs; + foreach my $a (@ARGV) { + if (TeXLive::TLUtils::member($a, @already_installed_arch)) { + print "Arch $a is already installed\n"; + next; + } + if (!TeXLive::TLUtils::member($a, @available_arch)) { + print "Arch $a not available, use 'tlmgr available_archs'!\n"; + next; + } + push @todoarchs, $a; + } + foreach my $pkg ($localtlpdb->list_packages) { + next if ($pkg =~ m/^00texlive/); + my $tlp = $localtlpdb->get_package($pkg); + foreach my $dep ($tlp->depends) { + if ($dep =~ m/^(.*)\.ARCH$/) { + # we have to install something + foreach my $a (@todoarchs) { + if ($opt_dry) { + print "Installing $pkg.$a\n"; + } else { + $ret |= $tlmediasrc->install_package("$pkg.$a", $localtlpdb, $opt_nodepends, 1); + } + } + } + } + } + if (TeXLive::TLUtils::member('win32', @todoarchs)) { + # install the necessary win32 stuff + $ret |= $tlmediasrc->install_package("bin-tlperl.win32", $localtlpdb, $opt_nodepends, 1); + $ret |= $tlmediasrc->install_package("bin-tlgs.win32", $localtlpdb, $opt_nodepends, 1); + } + } else { + die "Unknown option for arch: $what"; + } + return($ret); +} + +sub action_generate { + my $what = shift @ARGV; + my $localconf = ""; + my $dest = ""; + Getopt::Long::Configure(qw(no_pass_through)); + GetOptions("localcfg=s" => \$localconf, "dest=s" > \$dest,) or pod2usage(1); + init_local_db(); + if ($what =~ m/^language$/i) { + $dest || ($dest = kpsewhich ("TEXMFSYSVAR") . "/tex/generic/config/language.dat"); + $localconf || ($localconf = kpsewhich ("TEXMFLOCAL") . "/tex/generic/config/language-local.dat"); + tllog ($::LOG_NORMAL, "$0: writing language data to $dest\n"); + TeXLive::TLUtils::create_language ($localtlpdb, $dest, $localconf); + } elsif ($what =~ m/^fmtutil$/i) { + $dest || ($dest = kpsewhich("TEXMFSYSVAR") . "/web2c/fmtutil.cnf"); + $localconf || ($localconf = kpsewhich("TEXMFLOCAL") . "/web2c/fmtutil-local.cnf"); + tllog($::LOG_NORMAL, "writing fmtutil.cnf data to $dest\n"); + TeXLive::TLUtils::create_fmtutil($localtlpdb, $dest, $localconf); + } elsif ($what =~ m/^updmap$/i) { + $dest || ($dest = kpsewhich("TEXMFSYSVAR") . "/web2c/updmap.cfg"); + $localconf || ($localconf = kpsewhich("TEXMFLOCAL") . "/web2c/updmap-local.cfg"); + tllog($::LOG_NORMAL, "$0: writing new updmap.cfg to $dest\n"); + TeXLive::TLUtils::create_updmap ($localtlpdb, $dest, $localconf); + } else { + die "Unknown option for generate: $what"; + } + return(0); +} + +sub init_local_db { + $localtlpdb = TeXLive::TLPDB->new ("root" => "$Master"); + die("cannot find tlpdb!") unless (defined($localtlpdb)); + # setup the programs, for win32 we need the shipped wget/lzma etc, so we + # pass the location of these files to setup_programs. + setup_programs("$Master/tlpkg/installer", $localtlpdb->option_platform); + # let cmd line options override the settings in localtlpdb + my $loc = $localtlpdb->option_location; + if (defined($loc)) { + $location = $loc; + } + if (defined($opt_location)) { + $location = $opt_location; + } +} + +sub action_uninstall_win32 { + if (win32()) { + remove_texbindirs_from_path(); + unsetenv_reg("TEXBINDIR"); + # unregister_script_type(".texlua"); + unregister_uninstaller(); + exit if is_vista(); + broadcast_env(); + update_assocs(); + } +} + + +sub action_uninstall { + if (win32()) { + printf STDERR "Please use \"Add/Remove Programs\" from the Control Panel to removing TeX Live!\n"; + exit(1); + } + print("If you answer yes here the whole TeX Live installation will be removed!\n"); + print "Remove TeX Live (y/N): "; + my $yesno = ; + if ($yesno !~ m/^y(es)?$/i) { + print "Ok, cancelling the removal!\n"; + exit(0); + } + print ("Ok, removing the whole installation:\n"); + init_local_db; + my $tlpdb = $localtlpdb; + my $opt_symlinks = 0; + my ($sys_bin,$sys_info,$sys_man); + my ($texdir,$texmflocal,$texmfhome,$texmfsysvar); + if ($tlpdb) { + $sys_bin = $tlpdb->option_sys_bin; + $sys_man = $tlpdb->option_sys_man; + $sys_info= $tlpdb->option_sys_info; + $opt_symlinks = $tlpdb->option_symlinks; + $texdir = $Master; + $texmfhome = `kpsewhich -var-value=TEXMFHOME`; chomp($texmfhome); + $texmfsysvar = `kpsewhich -var-value=TEXMFSYSVAR`; chomp($texmfsysvar); + $texmflocal = `kpsewhich -var-value=TEXMFLOCAL`; chomp($texmflocal); + } else { + die("Cannot find tlpdb in $Master!"); + } + # remove the links missing + if ($opt_symlinks) { + my @files; + if ((-d "$sys_bin") && (-w "$sys_bin")) { + my $plat_bindir; + if (-l "$sys_bin/pdftex") { + my $fullpath = readlink("$sys_bin/pdftex"); + if ($fullpath =~ m;^$Master/bin/(.*)/[^/]*$;) { + $plat_bindir = $1; + } + } else { + warn "$sys_bin/pdftex not present or not a link, not removing any link of binaries!\n"; + } + if ($plat_bindir) { + @files = `ls "$Master/bin/$plat_bindir"`; + chomp(@files); + foreach my $f (@files) { + next if (! -r "$sys_bin/$f"); + if ((-l "$sys_bin/$f") && + (readlink("$sys_bin/$f") =~ m;^$Master/bin/$plat_bindir/;)) { + unlink("$sys_bin/$f"); + } else { + warn ("not removing $sys_bin/$f, not a link or wrong destination!\n"); + } + } + } + `rmdir "$sys_bin" 2>/dev/null`; + } else { + warn "destination of bin symlink $sys_bin not writable, no removal of links of bin files done!\n"; + } + # info files + if (-w $sys_info) { + @files = `ls "$Master/texmf/doc/info"`; + chomp(@files); + foreach my $f (@files) { + next if (! -r "$sys_info/$f"); + if ((-l "$sys_info/$f") && + (readlink("$sys_info/$f") =~ m;^$Master/texmf/doc/info/;)) { + unlink("$sys_info/$f"); + } else { + warn ("not removing $sys_info/$f, not a link or wrong destination!\n"); + } + } + `rmdir "$sys_info" 2>/dev/null`; + } else { + warn "destination of info symlink $sys_info not writable, no removal of links of info files done!\n"; + } + # man files + if (-w $sys_man) { + my $foo = `(cd "$Master/texmf/doc/man" && echo *)`; + my @mans = split ' ', $foo; + chomp(@mans); + foreach my $m (@mans) { + my $mandir = "$Master/texmf/doc/man/$m"; + next unless -d $mandir; + next unless -d "$sys_man/$m"; + @files = `ls "$mandir"`; + chomp(@files); + foreach my $f (@files) { + next if (! -r "$sys_man/$m/$f"); + if ((-l "$sys_man/$m/$f") && + (readlink("$sys_man/$m/$f") =~ m;^$Master/texmf/doc/man/$m/;)) { + unlink("$sys_man/$m/$f"); + } else { + warn ("not removing $sys_man/$m/$f, not a link or wrong destination!\n"); + } + } + # ignore errors, it might be not empty + `rmdir "$sys_man/$m" 2>/dev/null`; + } + `rmdir "$sys_man" 2>/dev/null`; + } else { + warn "destination of man symlink $sys_man not writable, no removal of links of man files done!\n"; + } + } + # + # now do remove the rest + system("rm", "-rf", "$texdir/texmf-dist"); + system("rm", "-rf", "$texdir/texmf-doc"); + system("rm", "-rf", "$texdir/texmf-var"); + system("rm", "-rf", "$texdir/texmf"); + system("rm", "-rf", "$texdir/tlpkg"); + system("rm", "-rf", "$texdir/bin"); + system("rmdir", "--ignore-fail-on-non-empty", "$texdir/temp"); + unlink("$texdir/install-tl.log"); + # should we do that???? + system("rm", "-rf", "$texdir/texmf-config"); + system("rmdir", "--ignore-fail-on-non-empty", "$texdir"); +} + + +# +# return all the directories from which all content will be removed +# +# idea: +# - create a hashes by_dir listing all files that should be removed +# by directory, i.e., key = dir, value is list of files +# - for each of the dirs (keys of by_dir and ordered deepest first) +# check that all actually contained files are removed +# and all the contained dirs are in the removal list. If this is the +# case put that directory into the removal list +# - return this removal list +# +sub removed_dirs +{ + my (@files) = @_; + my %removed_dirs; + my %by_dir; + + # construct hash of all directories mentioned, values are lists of the + # files/dirs in that directory. + for my $f (@files) { + my $abs_f = abs_path ($f); + if (!$abs_f) { + warn ("oops, no abs_path($f) from " . `pwd`); + next; + } + (my $d = $abs_f) =~ s,/[^/]*$,,; + my @a = exists $by_dir{$d} ? @{$by_dir{$d}} : (); + push (@a, $abs_f); + $by_dir{$d} = \@a; + } + + # for each of our directories, see if we are removing everything in + # the directory. if so, return the directory; else return the + # individual files. + for my $d (reverse sort keys %by_dir) { + opendir (DIR, $d) || die "opendir($d) failed: $!"; + my @dirents = readdir (DIR); + closedir (DIR) || warn "closedir($d) failed: $!"; + + # initialize test hash with all the files we saw in this dir. + # (These idioms are due to "Finding Elements in One Array and Not + # Another" in the Perl Cookbook.) + my %seen; + my @rmfiles = @{$by_dir{$d}}; + @seen{@rmfiles} = (); + + # see if everything is the same. + my $cleandir = 1; + for my $dirent (@dirents) { + next if $dirent =~ /^\.(\.|svn)?$/; # ignore . .. .svn + my $item = "$d/$dirent"; # prepend directory for comparison + if ( + ((-d $item) && (defined($removed_dirs{$item}))) + || + (exists $seen{$item}) + ) { + # do nothing + } else { + $cleandir = 0; + last; + } + } + if ($cleandir) { + $removed_dirs{$d} = 1; + } + } + return keys %removed_dirs; +} + +__END__ + +=head1 NAME + +tlmgr - the TeX Live Manager + +=head1 SYNOPSIS + +tlmgr ACTION [OPTIONS] ... + +=head1 ACTION + +=over 8 + +=item B + +Gives this help page. + +=item B + +Install all packages given on the cmdline. By default this installs all +dependencies, too. See below for the option B<-no-depends>. + +=item B + +Update all packages if newer ones are available + +=item B + +Remove all packages given on the cmdline. Removing a collection will +remove all dependencies, too, unless with option B<-no-depends>. + +Removing a package which is referenced as a dependency in another +collection or scheme will not succeed unless the B<-force> option is given. + +=item B + +=item B [C]> + +The first form shows the default settings as saved in the TeX Live Database. + +In the second form if the C is missing the setting is showed, while +with C present the setting is set to C. + +Possible values for C are: C (default installation source), +C (create formats at installation time), +C (install documentation files), +C (install source files). + +=item B + +=item B + +=item B<[xdvi|dvips|pdftex|dvipdfm|dvipdfmx] paper [help|papersize]> + +Configures the system wide paper settings, either for all programs in +one go, or for the given program on the command line. + +=item B + +Prints the list of arch-os available at the default install location. + +=item B + +Adds binaries for the given architectures to the installtion. + +=item B + +Search the names, short and long descriptions of all locally installed packages +for the given argument (interpreted as regexp). + +With the B<-file> argument searches for files containing C somewhere +in the path, and returning each package with the respective hit. + +=item B + +Search the names, short and long descriptions of all packages available on +the install media. + +With the B<-file> argument searches for files containing C somewhere +in the path, and returning each package with the respective hit. + +=item B + +Shows for each given package the name, category, installation status, +short and long description. Does search in the remote installation +source for finding the package if it is not installed. + + +=item B + +Without argument lists all packages available at the default install +location, prefixing those already installed with "i ". + +With arguments lists only collections or schemes. + +=item B + +Uninstalls the TeX Live installation. + +(This options is implemented in the texlua script and uninstall-tl.pl) + + +=item B + +=item B + +=item B + +Generate language.dat, fmtutil.cnf, and updmap.cfg from a TLPDB and local +additions + +B + +=over 16 + +=item C<-dest> I + +specifies the output file (defaults to the respective location in TEXMFSYSVAR). + +=item C<-localcfg> I + +specifies the (optional) local additions (defaults to the respective location +in TEXMFSYSVAR). + +=back + + +=back + +=head1 OPTIONS + +=over 8 + +=item B<-location> I + +Overrides the location as found in the tlpdb of the installation. Specifies +the location from which packages should be installed or updated. + +=item B<-no-depends> + +Do not install dependencies. If this option is not given installing +a package will check that all dependencies of this package are fulfilled. + +=item B<-force> + +When removing a package or collection would invalidate a dependency +of another collection/scheme, the package will not be removed and +a warning issued. With this options the package will be removed +unconditionally. Use with care. + +=item B<-dry-run> + +For installation and removal of packages, this options enables the chicken +mode, i.e., nothing is actually installed but the actions to be performed +are written to the terminal. + +Note that for all other type of options but package installation and removal +this options does B work! + +=item B<-netarchive> I + +Overrides the default settings for netarchive. Should be used with care. + +=item B<-diskarchive> I + +Overrides the default settings for diskarchive. Should be used with care. + +=back + +The standard options C<-help/-h/-?> and C<-debug> are also accepted. + +=head1 DESCRIPTION + +The B manages an existing TeX Live installation. + +=head1 AUTHORS AND COPYRIGHT + +This script and its documentation were written for the TeX Live +distribution (L) 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: # diff --git a/Master/texmf/scripts/texlive/tlmgr.tlu b/Master/texmf/scripts/texlive/tlmgr.tlu deleted file mode 100755 index d7c99d8a022..00000000000 --- a/Master/texmf/scripts/texlive/tlmgr.tlu +++ /dev/null @@ -1,180 +0,0 @@ -#! /usr/bin/env texlua ---*-Lua-*- --- $Id: tlmgr 7301 2008-04-03 16:52:55Z preining $ - --- Copyright (C) 2008 Reinhard Kotucha, Norbert Preining. --- You may freely use, modify and/or distribute this file. - --- tlmgr --- one central managment utility for TeX Live --- it calls several supporting scripts from texmf/scripts/texlive --- and other places --- --- NOTE --- The full documentation for the end user will be kept in --- tl-package-manager.pl --- since help or empty arguments will be forwarded to that script!!! --- --- Currently supported arguments --- generate-fmtutil generate-fmtutil.pl --- generate-updmap generate-updmap.pl --- generate-language generate-language.pl --- uninstall uninstall-tl.pl and local code --- anything else tl-package-manager.pl --- that is update, install, remove, search, ...... - -if string.find(arg[0], '/') then -- UNIX path - filename=select(1, string.gsub(arg[0], '.*/', '')) -elseif string.find(arg[0], '\\') then -- Windows path - filename=select(1, string.gsub(arg[0], '.*\\', '')) -else -- no path - filename=arg[0] -end - - --- we have to put the real calling program into basename. On win32 this --- will be the filename replacing tlu with texlua, on unix just the --- filename without extension --- -if os.type == 'windows' then - basename=select(1, string.gsub(filename, '\.tlu$', '.bat')) -else - basename=select(1, string.gsub(filename, '\.tlu$', '')) -end - -kpse.set_program_name(basename) -TEXDIR=kpse.var_value('SELFAUTOPARENT') -TEXMFSYSVAR=kpse.var_value('TEXMFSYSVAR') -BINDIR=kpse.var_value('SELFAUTOLOC') - --- set the search path for lua libraries -texmfmain = kpse.var_value('TEXMFMAIN') -package.path = texmfmain.."/scripts/texlive/lua/?.tlu" -require("texlive.utils") - --- setup perl once and for all -perlbin = setupperl() - -if arg[1] == 'uninstall' then - if os.type == 'windows' then - print ("Please use Add/Remove Programs from the Control Panel to remove TeX Live!") - os.exit(0); - end - print("If you answer yes here the whole TeX Live installation will be removed!") - io.stdout:write("Remove TeX Live (y/N): ") - local yesno = io.read() - if yesno == 'y' or yesno == 'Y' or yesno == 'yes' or yesno == 'YES' then - print ("Ok, removing the whole installation:") - -- we have to call perl uninstall-tl.pl AND have to remove the following - -- files: - -- TEXDIR/texmf{,-dist,-doc,-var,-config,}, TEXDIR/bin, TEXDIR/tlpkg, - -- TEXDIR/install-tl.log, TEXMFSYSVAR - -- that should remove all the stuff - -- Or other options? - script = findscript('uninstall-tl.pl') - if script then - command = { perlbin, script } - else - os.exit(1) - end - for i=1, #arg do - command[#command+1] = arg[i] - end - command = fixwin(command) - ret = os.spawn(command) - -- here we should check the return value!!! - if not ret then - io.stderr:write(filename..': The removal script uninstall-tl.pl returned false\n') - io.stderr:write(filename..": We don't continue removing stuff\n") - os.exit(1) - end - -- on windows we have now removed the associations etc, while - -- on unix we have removed the symlinks in case they were present - -- - -- now we have to remove all the files and directories - rmtree(TEXDIR.."/texmf-dist") - rmtree(TEXDIR.."/texmf-doc") - rmtree(TEXDIR.."/texmf-var") - rmtree(TEXDIR.."/texmf-config") - rmtree(TEXDIR.."/texmf") - rmtree(TEXDIR.."/tlpkg") - os.remove(TEXDIR.."/temp") - os.remove(TEXDIR.."/install-tl.log") - rmtree(TEXDIR.."/bin") - -- now everything should be removed, try to remove also TEXDIR - -- this will not succeed on win32 since texlua.exe is still in use - -- and thus removing TEXDIR/bin will not work. Damned. - os.remove(TEXDIR) - os.exit(0) - else - print("Ok, cancelling the removal.") - os.exit(0) - end -elseif arg[1] == 'generate' then - if arg[2] == 'fmtutil' then - script = findscript('generate-fmtutil.pl') - if script then - command = { perlbin, script } - else - print("tlmgr: Cannot find generate-fmtutil.pl, strange!") - os.exit(1) - end - elseif arg[2] == 'language' then - script = findscript('generate-language.pl') - if script then - command = { perlbin, script } - else - print("tlmgr: Cannot find generate-language.pl, strange!") - os.exit(1) - end - elseif arg[2] == 'updmap' then - script = findscript('generate-updmap.pl') - if script then - command = { perlbin, script } - else - print("tlmgr: Cannot find generate-updmap.pl, strange!") - os.exit(1) - end - else - print ("tlmgr: Unknown or missing argument for generate!") - os.exit(1) - end - -- support plain help - if arg[3] == 'help' then - arg[3] = '-help' - end -elseif arg[1] == 'paper' or - arg[1] == 'dvips' or arg[1] == 'xdvi' or arg[1] == 'pdftex' or - arg[1] == 'dvipdfm' or arg[1] == 'dvipdfmx' then - -- all changes made via tlmgr paper are global - script = findscript('texconf.tlu') - if script then - command = { 'texlua', script, '--prog', 'tlmgr', '--sys' } - else - os.exit(1) - end -else - -- in all other cases we call tl-package-manager for now ... - script = findscript('tl-package-manager.pl') - if script then - command = { perlbin, script } - else - os.exit(1) - end -end - -for i=1, #arg do - command[#command+1]=arg[i] -end - -command=fixwin(command) - -ret=os.spawn(command) -os.exit(ret) - --- Local Variables: --- perl-indent-level: 2 --- tab-width: 2 --- indent-tabs-mode: nil --- End: --- vim:set tabstop=2 expandtab: -- diff --git a/Master/texmf/scripts/texlive/uninstall-tl.pl b/Master/texmf/scripts/texlive/uninstall-tl.pl deleted file mode 100755 index ca19b63f7dc..00000000000 --- a/Master/texmf/scripts/texlive/uninstall-tl.pl +++ /dev/null @@ -1,155 +0,0 @@ -#!/usr/bin/env perl - -# $Id: uninstall-tl.pl 6381 2008-01-23 17:50:54Z preining $ -# uninstall-tl.pl -# -# Copyright 2008 Norbert Preining, Siep Kroonenberg -# This file is licensed under the GNU General Public License version 2 -# or any later version. -# - - -my $Master; - -BEGIN { - $^W = 1; - $Master = `kpsewhich -var-value=SELFAUTOPARENT`; - chomp($Master); - unshift (@INC, "$Master/tlpkg"); -} - - -use TeXLive::TLWinGoo; -use TeXLive::TLPDB; -use Cwd qw/abs_path/; -use strict; - -&main (); - -sub win32 -{ - return ($^O=~/^MSWin(32|64)$/i ? 1 : 0); -} - -sub main -{ - # get the db. - my $tlpdb = TeXLive::TLPDB->new ("root" => "$Master"); - my $opt_symlinks = 0; - my ($sys_bin,$sys_info,$sys_man); - my ($texdir,$texmflocal,$texmfhome,$texmfsysvar); - if ($tlpdb) { - $sys_bin = $tlpdb->option_sys_bin; - $sys_man = $tlpdb->option_sys_man; - $sys_info= $tlpdb->option_sys_info; - $opt_symlinks = $tlpdb->option_symlinks; - $texdir = $Master; - $texmfhome = `kpsewhich -var-value=TEXMFHOME`; chomp($texmfhome); - $texmfsysvar = `kpsewhich -var-value=TEXMFSYSVAR`; chomp($texmfsysvar); - $texmflocal = `kpsewhich -var-value=TEXMFLOCAL`; chomp($texmflocal); - } else { - warn("Cannot find tlpdb in $Master!\n"); - } - # we have to - # - (win32) remove the entry of bin/arch from the PATH environment - # - (unix) remove the links if opt_symlinks - # - (win32) remove the .texlua association - # - (win32) remove the entry of PATHEXT - # - (unix) ... the links - if (win32()) { - remove_texbindirs_from_path(); - unsetenv_reg("TEXBINDIR"); - unregister_script_type(".texlua"); - unregister_uninstaller(); - exit if is_vista(); - broadcast_env(); - update_assocs(); - } else { - # remove the links missing - if ($opt_symlinks) { - my @files; - if ((-d "$sys_bin") && (-w "$sys_bin")) { - my $plat_bindir; - if (-l "$sys_bin/pdftex") { - my $fullpath = readlink("$sys_bin/pdftex"); - if ($fullpath =~ m;^$Master/bin/(.*)/[^/]*$;) { - $plat_bindir = $1; - } - } else { - warn "$sys_bin/pdftex not present or not a link, not removing any link of binaries!\n"; - } - if ($plat_bindir) { - @files = `ls "$Master/bin/$plat_bindir"`; - chomp(@files); - foreach my $f (@files) { - next if (! -r "$sys_bin/$f"); - if ((-l "$sys_bin/$f") && - (readlink("$sys_bin/$f") =~ m;^$Master/bin/$plat_bindir/;)) { - unlink("$sys_bin/$f"); - } else { - warn ("not removing $sys_bin/$f, not a link or wrong destination!\n"); - } - } - } - `rmdir "$sys_bin" 2>/dev/null`; - } else { - warn "destination of bin symlink $sys_bin not writable, no removal of links of bin files done!\n"; - } - # info files - if (-w $sys_info) { - @files = `ls "$Master/texmf/doc/info"`; - chomp(@files); - foreach my $f (@files) { - next if (! -r "$sys_info/$f"); - if ((-l "$sys_info/$f") && - (readlink("$sys_info/$f") =~ m;^$Master/texmf/doc/info/;)) { - unlink("$sys_info/$f"); - } else { - warn ("not removing $sys_info/$f, not a link or wrong destination!\n"); - } - } - `rmdir "$sys_info" 2>/dev/null`; - } else { - warn "destination of info symlink $sys_info not writable, no removal of links of info files done!\n"; - } - # man files - if (-w $sys_man) { - my $foo = `(cd "$Master/texmf/doc/man" && echo *)`; - my @mans = split ' ', $foo; - chomp(@mans); - foreach my $m (@mans) { - my $mandir = "$Master/texmf/doc/man/$m"; - next unless -d $mandir; - next unless -d "$sys_man/$m"; - @files = `ls "$mandir"`; - chomp(@files); - foreach my $f (@files) { - next if (! -r "$sys_man/$m/$f"); - if ((-l "$sys_man/$m/$f") && - (readlink("$sys_man/$m/$f") =~ m;^$Master/texmf/doc/man/$m/;)) { - unlink("$sys_man/$m/$f"); - } else { - warn ("not removing $sys_man/$m/$f, not a link or wrong destination!\n"); - } - } - # ignore errors, it might be not empty - `rmdir "$sys_man/$m" 2>/dev/null`; - } - `rmdir "$sys_man" 2>/dev/null`; - } else { - warn "destination of man symlink $sys_man not writable, no removal of links of man files done!\n"; - } - } - } -} - - -__END__ - - -### Local Variables: -### perl-indent-level: 2 -### tab-width: 2 -### indent-tabs-mode: nil -### End: -# vim:set tabstop=2 expandtab: # diff --git a/Master/tlpkg/TeXLive/TLWinGoo.pm b/Master/tlpkg/TeXLive/TLWinGoo.pm index 03a5b2e6175..858369d3ba7 100644 --- a/Master/tlpkg/TeXLive/TLWinGoo.pm +++ b/Master/tlpkg/TeXLive/TLWinGoo.pm @@ -866,7 +866,7 @@ sub create_uninstaller { echo Do you really want to remove TeX Live 2008? Type Ctrl-C to abort. pause set PERL5LIB= -\"$td\\tlpkg\\tlperl\\bin\\perl.exe\" \"$td\\texmf\\scripts\\texlive\\uninstall-tl.pl\" +\"$td\\tlpkg\\tlperl\\bin\\perl.exe\" \"$td\\texmf\\scripts\\texlive\\tlmgr.pl\" uninstallwin32 copy \"$td\\tlpkg\\installer\\uninst2.bat\" \"\%TEMP\%\" \"\%TEMP\%\\uninst2.bat\" UNEND -- cgit v1.2.3