564 lines
20 KiB
Perl
Executable File
564 lines
20 KiB
Perl
Executable File
#! /usr/bin/perl --
|
|
|
|
#use POSIX; &ENOENT;
|
|
sub ENOENT { 2; }
|
|
# Sorry about this, but the errno-part of POSIX.pm isn't in perl-*-base
|
|
|
|
# Global variables:
|
|
# $alink Alternative we are managing (ie the symlink we're making/removing) (install only)
|
|
# $name Name of the alternative (the symlink) we are processing
|
|
# $apath Path of alternative we are offering
|
|
# $apriority Priority of link (only when we are installing an alternative)
|
|
# $mode action to perform (display / install / remove / display / auto / config)
|
|
# $manual update-mode for alternative (manual / auto)
|
|
# $state State of alternative:
|
|
# expected: alternative with highest priority is the active alternative
|
|
# expected-inprogress: busy selecting alternative with highest priority
|
|
# unexpected: alternative another alternative is active / error during readlink
|
|
# nonexistent: alternative-symlink does not exist
|
|
# $link Link we are working with
|
|
# @slavenames List with names of slavelinks
|
|
# %slavenum Map from name of slavelink to slave-index (into @slavelinks)
|
|
# @slavelinks List of slavelinks (indexed by slave-index)
|
|
# %versionnum Map from currently available versions into @versions and @priorities
|
|
# @versions List of available versions for alternative
|
|
# %priorities Map from @version-index to priority
|
|
# %slavepath Map from (@version-index,slavename) to slave-path
|
|
|
|
$version="1.8.3.ALT"; # This line modified by Makefile
|
|
sub usageversion {
|
|
print(STDERR <<END)
|
|
The update-alternatives $version. Copyright (C) 1995 Ian Jackson.
|
|
This is free software; see the GNU General Public Licence
|
|
version 2 or later for copying conditions. There is NO warranty.
|
|
|
|
Usage: update-alternatives --install <link> <name> <path> <priority>
|
|
[--slave <link> <name> <path>] ...
|
|
update-alternatives --remove <name> <path>
|
|
update-alternatives --auto <name>
|
|
update-alternatives --display <name>
|
|
update-alternatives --config <name> [<path>]
|
|
<name> is the name in /etc/alternatives.
|
|
<path> is the name referred to.
|
|
<link> is the link pointing to /etc/alternatives/<name>.
|
|
<priority> is an integer; options with higher numbers are chosen.
|
|
|
|
Options: --verbose|--quiet --test --help --version
|
|
--altdir <directory> --admindir <directory>
|
|
END
|
|
|| &quit("failed to write usage: $!");
|
|
}
|
|
sub quit { print STDERR "update-alternatives: @_\n"; exit(2); }
|
|
sub badusage { print STDERR "update-alternatives: @_\n\n"; &usageversion; exit(2); }
|
|
|
|
$altdir= '/etc/alternatives';
|
|
$admindir= '/var/lib/rpm/alternatives';
|
|
$testmode= 0;
|
|
$verbosemode= 0;
|
|
$mode='';
|
|
$manual= 'auto';
|
|
$|=1;
|
|
|
|
sub checkmanymodes {
|
|
return unless $mode;
|
|
&badusage("two modes specified: $_ and --$mode");
|
|
}
|
|
|
|
while (@ARGV) {
|
|
$_= shift(@ARGV);
|
|
last if m/^--$/;
|
|
if (!m/^--/) {
|
|
&quit("unknown argument \`$_'");
|
|
} elsif (m/^--(help|version)$/) {
|
|
&usageversion; exit(0);
|
|
} elsif (m/^--test$/) {
|
|
$testmode= 1;
|
|
} elsif (m/^--verbose$/) {
|
|
$verbosemode= +1;
|
|
} elsif (m/^--quiet$/) {
|
|
$verbosemode= -1;
|
|
} elsif (m/^--install$/) {
|
|
&checkmanymodes;
|
|
@ARGV >= 4 || &badusage("--install needs <link> <name> <path> <priority>");
|
|
($alink,$name,$apath,$apriority,@ARGV) = @ARGV;
|
|
$apriority =~ m/^[-+]?\d+/ || &badusage("priority must be an integer");
|
|
$mode= 'install';
|
|
} elsif (m/^--remove$/) {
|
|
&checkmanymodes;
|
|
@ARGV >= 2 || &badusage("--remove needs <name> <path>");
|
|
($name,$apath,@ARGV) = @ARGV;
|
|
$mode= 'remove';
|
|
} elsif (m/^--(display|auto)$/) {
|
|
&checkmanymodes;
|
|
@ARGV || &badusage("--$1 needs <name>");
|
|
$mode= $1;
|
|
$name= shift(@ARGV);
|
|
} elsif (m/^--config$/) {
|
|
&checkmanymodes;
|
|
@ARGV || &badusage("--config needs <name> [<path>]");
|
|
($name,$apath,@ARGV) = @ARGV;
|
|
$mode= 'config';
|
|
} elsif (m/^--slave$/) {
|
|
@ARGV >= 3 || &badusage("--slave needs <link> <name> <path>");
|
|
($slink,$sname,$spath,@ARGV) = @ARGV;
|
|
defined($aslavelink{$sname}) && &badusage("slave name $sname duplicated");
|
|
$aslavelinkcount{$slink}++ && &badusage("slave link $slink duplicated");
|
|
$aslavelink{$sname}= $slink;
|
|
$aslavepath{$sname}= $spath;
|
|
} elsif (m/^--altdir$/) {
|
|
@ARGV || &badusage("--altdir needs a <directory> argument");
|
|
$altdir= shift(@ARGV);
|
|
} elsif (m/^--admindir$/) {
|
|
@ARGV || &badusage("--admindir needs a <directory> argument");
|
|
$admindir= shift(@ARGV);
|
|
} else {
|
|
&badusage("unknown option \`$_'");
|
|
}
|
|
}
|
|
|
|
defined($aslavelink{$name}) && &badusage("name $name is both primary and slave");
|
|
$aslavelinkcount{$alink} && &badusage("link $link is both primary and slave");
|
|
|
|
$mode || &badusage("need --display, --config, --install, --remove or --auto");
|
|
$mode eq 'install' || !%aslavelink || &badusage("--slave only allowed with --install");
|
|
|
|
if (open(AF,"$admindir/$name")) {
|
|
$manual= &gl("manflag");
|
|
$manual eq 'auto' || $manual eq 'manual' || &badfmt("manflag");
|
|
$link= &gl("link");
|
|
while (($sname= &gl("sname")) ne '') {
|
|
push(@slavenames,$sname);
|
|
defined($slavenum{$sname}) && &badfmt("duplicate slave $sname");
|
|
$slavenum{$sname}= $#slavenames;
|
|
$slink= &gl("slink");
|
|
$slink eq $link && &badfmt("slave link same as main link $link");
|
|
$slavelinkcount{$slink}++ && &badfmt("duplicate slave link $slink");
|
|
push(@slavelinks,$slink);
|
|
}
|
|
while (($version= &gl("version")) ne '') {
|
|
defined($versionnum{$version}) && &badfmt("duplicate path $version");
|
|
if ( -e $version ) {
|
|
push(@versions,$version);
|
|
$versionnum{$version}= $i= $#versions;
|
|
$priority= &gl("priority");
|
|
$priority =~ m/^[-+]?\d+$/ || &badfmt("priority $version $priority");
|
|
$priorities[$i]= $priority;
|
|
for ($j=0; $j<=$#slavenames; $j++) {
|
|
$slavepath{$i,$j}= &gl("spath");
|
|
}
|
|
} else {
|
|
# File not found - remove
|
|
&pr("Alternative for $name points to $version - which wasn't found. Removing from list of alternatives.")
|
|
if $verbosemode > 0;
|
|
&gl("priority");
|
|
for ($j=0; $j<=$#slavenames; $j++) {
|
|
&gl("spath");
|
|
}
|
|
}
|
|
}
|
|
close(AF);
|
|
$dataread=1;
|
|
} elsif ($! != &ENOENT) {
|
|
&quit("failed to open $admindir/$name: $!");
|
|
}
|
|
|
|
$best= '';
|
|
for ($i=0; $i<=$#versions; $i++) {
|
|
if ($best eq '' || $priorities[$i] > $bestpri) {
|
|
$best= $versions[$i]; $bestpri= $priorities[$i];
|
|
}
|
|
}
|
|
|
|
if ($mode eq 'display') {
|
|
if (!$dataread) {
|
|
&quit("No alternatives found for $name.");
|
|
} else {
|
|
&pr("$name - status is $manual.");
|
|
if (defined($linkname= readlink("$altdir/$name"))) {
|
|
&pr(" link currently points to $linkname");
|
|
} elsif ($! == &ENOENT) {
|
|
&pr(" link currently absent");
|
|
} else {
|
|
&pr(" link unreadable - $!");
|
|
}
|
|
for ($i=0; $i<=$#versions; $i++) {
|
|
&pr("$versions[$i] - priority $priorities[$i]");
|
|
for ($j=0; $j<=$#slavenames; $j++) {
|
|
next unless length($tspath= $slavepath{$i,$j});
|
|
&pr(" slave $slavenames[$j]: $tspath");
|
|
}
|
|
}
|
|
if ($best eq '') {
|
|
&pr("No versions available.");
|
|
} else {
|
|
&pr("Current \`best' version is $best.");
|
|
}
|
|
}
|
|
exit 0;
|
|
}
|
|
|
|
if ($mode eq 'config') {
|
|
if (!$dataread) {
|
|
&quit("No alternatives found for $name.");
|
|
} else {
|
|
&config_alternatives($name);
|
|
}
|
|
}
|
|
|
|
if (defined($linkname= readlink("$altdir/$name"))) {
|
|
if ($linkname eq $best) {
|
|
$state= 'expected';
|
|
} elsif (defined(readlink("$altdir/$name.rpm-tmp"))) {
|
|
$state= 'expected-inprogress';
|
|
} else {
|
|
$state= 'unexpected';
|
|
}
|
|
} elsif ($! == &ENOENT) {
|
|
$state= 'nonexistent';
|
|
} else {
|
|
$state= 'unexpected';
|
|
}
|
|
|
|
# Possible values for:
|
|
# $manual manual, auto
|
|
# $state expected, expected-inprogress, unexpected, nonexistent
|
|
# $mode auto, install, remove
|
|
# all independent
|
|
|
|
if ($mode eq 'auto') {
|
|
&pr("Setting up automatic selection of $name.")
|
|
if $verbosemode > 0;
|
|
unlink("$altdir/$name.rpm-tmp") || $! == &ENOENT ||
|
|
&quit("unable to remove $altdir/$name.rpm-tmp: $!");
|
|
unlink("$altdir/$name") || $! == &ENOENT ||
|
|
&quit("unable to remove $altdir/$name.rpm-tmp: $!");
|
|
$state= 'nonexistent';
|
|
$manual= 'auto';
|
|
} elsif ($state eq 'nonexistent') {
|
|
if ($manual eq 'manual') {
|
|
&pr("$altdir/$name has been deleted, returning to automatic selection.")
|
|
if $verbosemode > 0;
|
|
$manual= 'auto';
|
|
}
|
|
}
|
|
|
|
# $manual manual, auto
|
|
# $state expected, expected-inprogress, unexpected, nonexistent
|
|
# $mode auto, install, remove
|
|
# mode=auto <=> state=nonexistent
|
|
|
|
if ($state eq 'unexpected' && $manual eq 'auto') {
|
|
&pr("$altdir/$name has been changed (manually or by a script).\n".
|
|
"Switching to manual updates only.")
|
|
if $verbosemode > 0;
|
|
$manual= 'manual';
|
|
}
|
|
|
|
# $manual manual, auto
|
|
# $state expected, expected-inprogress, unexpected, nonexistent
|
|
# $mode auto, install, remove
|
|
# mode=auto <=> state=nonexistent
|
|
# state=unexpected => manual=manual
|
|
|
|
&pr("Checking available versions of $name, updating links in $altdir ...\n".
|
|
"(You may modify the symlinks there yourself if desired - see \`man ln'.)")
|
|
if $verbosemode > 0;
|
|
|
|
if ($mode eq 'install') {
|
|
if ($link ne $alink && $link ne '') {
|
|
&pr("Renaming $name link from $link to $alink.")
|
|
if $verbosemode > 0;
|
|
&rename_mv($link,$alink) || $! == &ENOENT ||
|
|
&quit("unable to rename $link to $alink: $!");
|
|
}
|
|
$link= $alink;
|
|
if (!defined($i= $versionnum{$apath})) {
|
|
push(@versions,$apath);
|
|
$versionnum{$apath}= $i= $#versions;
|
|
}
|
|
$priorities[$i]= $apriority;
|
|
for $sname (keys %aslavelink) {
|
|
if (!defined($j= $slavenum{$sname})) {
|
|
push(@slavenames,$sname);
|
|
$slavenum{$sname}= $j= $#slavenames;
|
|
}
|
|
$oldslavelink= $slavelinks[$j];
|
|
$newslavelink= $aslavelink{$sname};
|
|
$slavelinkcount{$oldslavelink}-- if $oldslavelink ne '';
|
|
$slavelinkcount{$newslavelink}++ &&
|
|
&quit("slave link name $newslavelink duplicated");
|
|
if ($newslavelink ne $oldslavelink && $oldslavelink ne '') {
|
|
&pr("Renaming $sname slave link from $oldslavelink to $newslavelink.")
|
|
if $verbosemode > 0;
|
|
&rename_mv($oldslavelink,$newslavelink) || $! == &ENOENT ||
|
|
&quit("unable to rename $oldslavelink to $newslavelink: $!");
|
|
}
|
|
$slavelinks[$j]= $newslavelink;
|
|
}
|
|
for ($j=0; $j<=$#slavenames; $j++) {
|
|
$slavepath{$i,$j}= $aslavepath{$slavenames[$j]};
|
|
}
|
|
}
|
|
|
|
if ($mode eq 'remove') {
|
|
if ($manual eq "manual" and $state eq "expected") {
|
|
&pr("Removing manually selected alternative - switching to auto mode");
|
|
$manual= "auto";
|
|
}
|
|
if (defined($i= $versionnum{$apath})) {
|
|
$k= $#versions;
|
|
$versionnum{$versions[$k]}= $i;
|
|
delete $versionnum{$versions[$i]};
|
|
$versions[$i]= $versions[$k]; $#versions--;
|
|
$priorities[$i]= $priorities[$k]; $#priorities--;
|
|
for ($j=0; $j<=$#slavenames; $j++) {
|
|
$slavepath{$i,$j}= $slavepath{$k,$j};
|
|
delete $slavepath{$k,$j};
|
|
}
|
|
} else {
|
|
&pr("Alternative $apath for $name not registered, not removing.")
|
|
if $verbosemode > 0;
|
|
}
|
|
}
|
|
|
|
for ($j=0; $j<=$#slavenames; $j++) {
|
|
for ($i=0; $i<=$#versions; $i++) {
|
|
last if $slavepath{$i,$j} ne '';
|
|
}
|
|
if ($i > $#versions) {
|
|
&pr("Discarding obsolete slave link $slavenames[$j] ($slavelinks[$j]).")
|
|
if $verbosemode > 0;
|
|
unlink("$altdir/$slavenames[$j]") || $! == &ENOENT ||
|
|
&quit("unable to remove $slavenames[$j]: $!");
|
|
unlink($slavelinks[$j]) || $! == &ENOENT ||
|
|
&quit("unable to remove $slavelinks[$j]: $!");
|
|
$k= $#slavenames;
|
|
$slavenum{$slavenames[$k]}= $j;
|
|
delete $slavenum{$slavenames[$j]};
|
|
$slavelinkcount{$slavelinks[$j]}--;
|
|
$slavenames[$j]= $slavenames[$k]; $#slavenames--;
|
|
$slavelinks[$j]= $slavelinks[$k]; $#slavelinks--;
|
|
for ($i=0; $i<=$#versions; $i++) {
|
|
$slavepath{$i,$j}= $slavepath{$i,$k};
|
|
delete $slavepath{$i,$k};
|
|
}
|
|
$j--;
|
|
}
|
|
}
|
|
|
|
if ($manual eq 'manual') {
|
|
&pr("Automatic updates of $altdir/$name are disabled, leaving it alone.")
|
|
if $verbosemode > 0;
|
|
&pr("To return to automatic updates use \`update-alternatives --auto $name'.")
|
|
if $verbosemode > 0;
|
|
} else {
|
|
if ($state eq 'expected-inprogress') {
|
|
&pr("Recovering from previous failed update of $name ...");
|
|
rename("$altdir/$name.rpm-tmp","$altdir/$name") ||
|
|
&quit("unable to rename $altdir/$name.rpm-tmp to $altdir/$name: $!");
|
|
$state= 'expected';
|
|
}
|
|
}
|
|
|
|
# $manual manual, auto
|
|
# $state expected, expected-inprogress, unexpected, nonexistent
|
|
# $mode auto, install, remove
|
|
# mode=auto <=> state=nonexistent
|
|
# state=unexpected => manual=manual
|
|
# manual=auto => state!=expected-inprogress && state!=unexpected
|
|
|
|
open(AF,">$admindir/$name.rpm-new") ||
|
|
&quit("unable to open $admindir/$name.rpm-new for write: $!");
|
|
&paf($manual);
|
|
&paf($link);
|
|
for ($j=0; $j<=$#slavenames; $j++) {
|
|
&paf($slavenames[$j]);
|
|
&paf($slavelinks[$j]);
|
|
}
|
|
&paf('');
|
|
$best= '';
|
|
for ($i=0; $i<=$#versions; $i++) {
|
|
if ($best eq '' || $priorities[$i] > $bestpri) {
|
|
$best= $versions[$i]; $bestpri= $priorities[$i]; $bestnum= $i;
|
|
}
|
|
&paf($versions[$i]);
|
|
&paf($priorities[$i]);
|
|
for ($j=0; $j<=$#slavenames; $j++) {
|
|
&paf($slavepath{$i,$j});
|
|
}
|
|
}
|
|
&paf('');
|
|
close(AF) || &quit("unable to close $admindir/$name.rpm-new: $!");
|
|
|
|
if ($manual eq 'auto') {
|
|
if ($best eq '') {
|
|
&pr("Last package providing $name ($link) removed, deleting it.")
|
|
if $verbosemode > 0;
|
|
unlink("$altdir/$name") || $! == &ENOENT ||
|
|
&quit("unable to remove $altdir/$name: $!");
|
|
unlink("$link") || $! == &ENOENT ||
|
|
&quit("unable to remove $altdir/$name: $!");
|
|
unlink("$admindir/$name.rpm-new") ||
|
|
&quit("unable to remove $admindir/$name.rpm-new: $!");
|
|
unlink("$admindir/$name") || $! == &ENOENT ||
|
|
&quit("unable to remove $admindir/$name: $!");
|
|
exit(0);
|
|
} else {
|
|
if (!defined($linkname= readlink($link)) && $! != &ENOENT) {
|
|
&pr("warning: $link is supposed to be a symlink to $altdir/$name\n".
|
|
" (or nonexistent); however, readlink failed: $!")
|
|
if $verbosemode > 0;
|
|
} elsif ($linkname ne "$altdir/$name") {
|
|
&tmped_symlink("$altdir/$name",$link);
|
|
}
|
|
if (defined($linkname= readlink("$altdir/$name")) && $linkname eq $best) {
|
|
&pr("Leaving $name ($link) pointing to $best.")
|
|
if $verbosemode > 0;
|
|
} else {
|
|
&pr("Updating $name ($link) to point to $best.")
|
|
if $verbosemode > 0;
|
|
}
|
|
&checked_symlink($best,"$altdir/$name.rpm-tmp");
|
|
}
|
|
}
|
|
|
|
rename("$admindir/$name.rpm-new","$admindir/$name") ||
|
|
&quit("unable to rename $admindir/$name.rpm-new to $admindir/$name: $!");
|
|
|
|
if ($manual eq 'auto') {
|
|
&checked_mv("$altdir/$name.rpm-tmp","$altdir/$name");
|
|
for ($j=0; $j<=$#slavenames; $j++) {
|
|
$sname= $slavenames[$j];
|
|
$slink= $slavelinks[$j];
|
|
if (!defined($linkname= readlink($slink)) && $! != &ENOENT) {
|
|
&pr("warning: $slink is supposed to be a slave symlink to\n".
|
|
" $altdir/$sname, or nonexistent; however, readlink failed: $!")
|
|
if $verbosemode > 0;
|
|
} elsif ($linkname ne "$altdir/$sname") {
|
|
&tmped_symlink("$altdir/$sname",$slink);
|
|
}
|
|
$spath= $slavepath{$bestnum,$j};
|
|
unlink("$altdir/$sname.rpm-tmp") || $! == &ENOENT ||
|
|
&quit("unable to ensure $altdir/$sname.rpm-tmp nonexistent: $!");
|
|
if ($spath eq '') {
|
|
&pr("Removing $sname ($slink), not appropriate with $best.")
|
|
if $verbosemode > 0;
|
|
unlink("$altdir/$sname") || $! == &ENOENT ||
|
|
&quit("unable to remove $altdir/$sname: $!");
|
|
unlink("$slink") || $! == &ENOENT ||
|
|
&quit("unable to remove $slink: $!");
|
|
} else {
|
|
if (defined($linkname= readlink("$altdir/$sname")) && $linkname eq $spath) {
|
|
&pr("Leaving $sname ($slink) pointing to $spath.")
|
|
if $verbosemode > 0;
|
|
} else {
|
|
&pr("Updating $sname ($slink) to point to $spath.")
|
|
if $verbosemode > 0;
|
|
}
|
|
&tmped_symlink("$spath","$altdir/$sname");
|
|
}
|
|
}
|
|
}
|
|
|
|
sub config_message {
|
|
if ($#versions == 0) {
|
|
&pr("\nThere is only 1 program which provides $name");
|
|
&pr("($versions[0]). Nothing to configure.");
|
|
exit(0);
|
|
}
|
|
printf(STDOUT "\nThere are %s programs which provide \`$name'.\n\n", $#versions+1);
|
|
printf(STDOUT " Selection Command\n");
|
|
printf(STDOUT "-----------------------------------------------\n");
|
|
for ($i=0; $i<=$#versions; $i++) {
|
|
printf(STDOUT "%s%s %s %s\n",
|
|
(readlink("$altdir/$name") eq $versions[$i]) ? '*' : ' ',
|
|
($best eq $versions[$i]) ? '+' : ' ',
|
|
$i+1, $versions[$i]);
|
|
}
|
|
printf(STDOUT "\nEnter to keep the default[*], or type selection number: ");
|
|
}
|
|
|
|
sub config_alternative {
|
|
my ($preferred) = @_;
|
|
$manual = "manual";
|
|
&pr("Using \`$versions[$preferred]' to provide \`$name'.");
|
|
my $spath = $versions[$preferred];
|
|
&tmped_symlink("$spath","$altdir/$name");
|
|
#Link slaves...
|
|
for( my $slnum = 0; $slnum < @slavenames; $slnum++ ) {
|
|
my $slave = $slavenames[$slnum];
|
|
if ($slavepath{$preferred,$slnum} ne '') {
|
|
&tmped_symlink($slavepath{$preferred,$slnum}, "$altdir/$slave");
|
|
} else {
|
|
&pr("Removing $slave ($slavelinks[$slnum]), not appropriate with $versions[$preferred].")
|
|
if $verbosemode > 0;
|
|
unlink("$altdir/$slave") || $! == &ENOENT ||
|
|
&quit("unable to remove $altdir/$slave: $!");
|
|
}
|
|
}
|
|
exit(0);
|
|
}
|
|
|
|
sub config_alternatives {
|
|
if (defined($apath)) {
|
|
if (defined($i= $versionnum{$apath})) {
|
|
&config_alternative($i);
|
|
} else {
|
|
&quit("Alternative $apath for $name not registered.");
|
|
}
|
|
}
|
|
do {
|
|
&config_message;
|
|
$preferred=<STDIN>;
|
|
chop($preferred);
|
|
} until $preferred eq '' || $preferred>=1 && $preferred<=$#versions+1 &&
|
|
($preferred =~ m/[0-9]*/);
|
|
if ($preferred ne '') {
|
|
$preferred--;
|
|
&config_alternative($preferred);
|
|
} else {
|
|
&quit("Nothing selected.");
|
|
}
|
|
}
|
|
|
|
sub pr { print(STDOUT "@_\n") || &quit("error writing stdout: $!"); }
|
|
sub paf {
|
|
$_[0] =~ m/\n/ && &quit("newlines prohibited in update-alternatives files ($_[0])");
|
|
print(AF "$_[0]\n") || &quit("error writing stdout: $!");
|
|
}
|
|
sub gl {
|
|
$!=0; $_= <AF>;
|
|
length($_) || &quit("error or eof reading $admindir/$name for $_[0] ($!)");
|
|
s/\n$// || &badfmt("missing newline after $_[0]");
|
|
$_;
|
|
}
|
|
sub badfmt {
|
|
&quit("internal error: $admindir/$name corrupt: $_[0]");
|
|
}
|
|
sub rename_mv {
|
|
return (rename($_[0], $_[1]) || (system(("mv", $_[0], $_[1])) == 0));
|
|
}
|
|
sub checked_symlink {
|
|
my ($filename, $linkname) = @_;
|
|
unlink($linkname) || $! == &ENOENT ||
|
|
&quit("unable to ensure $linkname nonexistent: $!");
|
|
symlink($filename,$linkname) ||
|
|
&quit("unable to symlink $linkname to $filename: $!");
|
|
}
|
|
sub checked_mv {
|
|
my ($source, $dest) = @_;
|
|
&rename_mv($source, $dest) ||
|
|
&quit("unable to install $source as $dest: $!");
|
|
}
|
|
sub tmped_symlink {
|
|
my ($filename, $linkname) = @_;
|
|
my $tmplink = "$linkname.rpm-tmp";
|
|
|
|
&checked_symlink($filename,$tmplink);
|
|
&checked_mv($tmplink,$linkname);
|
|
}
|
|
|
|
exit(0);
|
|
|
|
# vim: nowrap ts=8 sw=4
|