summaryrefslogtreecommitdiffstats
path: root/urpmi
diff options
context:
space:
mode:
authorPascal Rigaux <pixel@mandriva.com>1999-12-17 00:21:09 +0000
committerPascal Rigaux <pixel@mandriva.com>1999-12-17 00:21:09 +0000
commit2b6d115da4ba39a0b30eb6e014684d82101f3265 (patch)
tree7ead586efca6413473c0b880d976f3dc5d7f2849 /urpmi
parent8bc2804dffe993ded66f55ec4a6d13d9e8ed0bd7 (diff)
downloadurpmi-2b6d115da4ba39a0b30eb6e014684d82101f3265.tar
urpmi-2b6d115da4ba39a0b30eb6e014684d82101f3265.tar.gz
urpmi-2b6d115da4ba39a0b30eb6e014684d82101f3265.tar.bz2
urpmi-2b6d115da4ba39a0b30eb6e014684d82101f3265.tar.xz
urpmi-2b6d115da4ba39a0b30eb6e014684d82101f3265.zip
no_comment
Diffstat (limited to 'urpmi')
-rwxr-xr-xurpmi246
1 files changed, 246 insertions, 0 deletions
diff --git a/urpmi b/urpmi
new file mode 100755
index 00000000..84c282cc
--- /dev/null
+++ b/urpmi
@@ -0,0 +1,246 @@
+#!/usr/bin/perl -U
+
+my $lang = $ENV{LC_ALL} || $ENV{LANGUAGE} || $ENV{LC_MESSAGES} || $ENV{LANG};
+load_po(substr($lang, 0, 2));
+
+$ENV{PATH} = "/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin";
+$< = $>;
+
+
+open LOG, ">>/var/log/urpmi.log" or die;
+print LOG scalar localtime, " urpmi called with @ARGV\n";
+close LOG;
+
+if (@ARGV and $ARGV[0] eq '--auto') {
+ $auto = 1;
+ shift @ARGV;
+}
+
+if (@ARGV and $ARGV[0] eq '--X') {
+ $X = 1;
+ shift @ARGV;
+}
+
+while (@ARGV and $ARGV[0] eq '--comment') {
+ shift @ARGV;
+ shift @ARGV;
+}
+
+@ARGV or die "usage: urpmi [--auto] package_name [package_names...]\n";
+
+$dir = "/etc/urpmi";
+$depsfile = "$dir/depslist";
+$rpmlistfiles = "$dir/list.*";
+
+open SAVEOUT, ">&STDOUT";
+open SAVEERR, ">&STDERR";
+open STDOUT, "|tee -a /var/log/urpmi.installed" or die;
+open STDERR, "|tee -a /var/log/urpmi.log" or die;
+select STDERR; $| = 1; # make unbuffered
+select STDOUT; $| = 1; # make unbuffered
+
+open F, $depsfile or die();
+foreach (<F>) {
+ my ($pack, $deps) = /(\S+)\s+\S+\s+(.*)/ or die("urpmi: bad format file $depsfile\n");
+ $deps{$pack} = [ split ' ', $deps ];
+
+ foreach $v (@ARGV) {
+ $_ = quotemeta $v;
+ $pack =~ /^$_-[^-]+-[^-]+$/ and $exact{$v} = $pack;
+ $pack =~ /^$_-[^-]+$/ and $exact{$v} = $pack;
+ $pack =~ /^$_$/ and $exact{$v} = $pack;
+ $pack =~ /$_/ and push @{$found{$v}}, $pack;
+ $pack =~ /$_/i and push @{$foundi{$v}}, $pack;
+ }
+}
+close F or die();
+
+my $ok = 1;
+foreach (@ARGV) {
+ my $pack = $exact{$_};
+ unless ($pack) {
+ my $l = $found{$_}; $l or $l = $foundi{$_};
+ if (@$l == 0) { warn(_("no package named %s\n", $_)); $ok = 0; }
+ elsif (@$l > 1) { warn(_("The following packages contain %s: %s\n", $_, join(', ', @$l))); $ok = 0; }
+ $pack = $$l[0];
+ }
+ push @packages, $pack;
+}
+$ok or exit 1;
+
+@installed = `/bin/rpm -qa`; $? and die(_("rpm database query failed\n"));
+foreach (@installed) {
+ my ($name, $v, $r) = /(.*)-([^-]+)-([^-.]+)/;
+ exists $installed{$name} && le_version([$v, $r], $installed{$name}) or $installed{$name} = [$v, $r];
+}
+@installed{map { chop; $_ } @installed} = ();
+my %to_install; closure_deps(\%to_install, @packages); @to_install = keys %to_install;
+
+if (!$auto and difference2(\@to_install, \@packages)) {
+ my $msg = _("To satisfy dependencies, the following packages are going to be installed");
+ my $msg2 = _("Is it ok?");
+ if ($X) {
+ my $p = join "\n", @to_install;
+ my $ok = _("Ok");
+ my $cancel = _("Cancel");
+ `gmessage -default $ok -buttons "$ok:0,$cancel:2" "$msg:\n$p\n\n$msg2"`;
+ $? and exit 0;
+ } else {
+ print SAVEOUT "$msg:\n@to_install\n$msg2 (y/n) ";
+ <STDIN> =~ /y/i or exit 0;
+ }
+}
+
+$to_install = join '|', map { quotemeta($_) } @to_install;
+
+foreach $file (glob($rpmlistfiles)) {
+ open F, $file or die("urpmi: error opening $file\n");
+ $file =~ s|.*/list\.(.*?)|$1|;
+ foreach (<F>) { chop; m|/($to_install)| and $long{$1} = $_, $name{$1} = $file; }
+ close F;
+}
+foreach $l (@to_install) {
+ local $_ = $long{$l} or die("urpmi: package $l is not available\n");
+ if (s|removable_(\w+)_(\d*):/||) {
+ my $n = "$2-$name{$l}";
+ $removables{$n}->{name} = $name{$l};
+ $removables{$n}->{device} = $1;
+ push @{$removables{$n}->{list}}, $_;
+ } else {
+ s|^file:/||;
+ push @to_install_long, $_;
+ }
+}
+
+foreach (sort keys %removables) {
+ my $f = @{$removables{$_}->{list}}[0];
+ my $dev = $removables{$_}->{device};
+ `mount /dev/$dev 2>/dev/null`;
+ unless (-e $f) {
+ `umount /dev/$dev 2>/dev/null ; eject $dev 2>/dev/null`;
+ message(_("Please insert the %s named %s", $removables{$_}->{device}, $removables{$_}->{name}));
+ unless ($X) {
+ print SAVEOUT _("Press enter when it's done...");
+ <STDIN>;
+ }
+ `mount /dev/$dev 2>/dev/null`;
+ unless (-e $f) {
+ message(_("Sorry can't find file %s, exiting", $f));
+ exit 1;
+ }
+ }
+ install(@{$removables{$_}->{list}});
+}
+
+install(@to_install_long);
+$something_was_installed or message(_("everything already installed"));
+
+sub install {
+ @_ or return;
+
+ $something_was_installed = 1;
+ print SAVEOUT _("installing %s\n", join(' ', @_));
+ print scalar localtime, " @_\n";
+ $X ? `grpmi @_` : `rpm -U @_`;
+ $? and message(_("Installation failed")), exit 1;
+}
+
+# uses @deps and @installed
+sub closure_deps {
+ my $to_install = shift;
+ foreach (@_) {
+ exists $to_install->{$_} and next;
+ my ($name, $v, $r) = /(.*)-([^-]+)-([^-.]+)/;
+ exists $installed{$name} && le_version([$v, $r], $installed{$name}) and next;
+
+ $to_install->{$_} = undef;
+ my @d = @{$deps{$_}} or return $_;
+ up: foreach (@d) {
+ my %l;
+ foreach (split '\|') {
+ exists $to_install->{$_} and next up;
+ my ($name, $v, $r) = /(.*)-([^-]+)-([^-.]+)/;
+ if (exists $installed{$name}) {
+ le_version([$v, $r], $installed{$name}) and next up;
+ %l = ($name => [$v, $r]);
+ last;
+ }
+ $l{$name} = [$v, $r] unless $l{$name} && le_version([$v, $r], $l{$name});
+ }
+ my ($l) = my @l = map { "$_-$l{$_}[0]-$l{$_}[1]" } keys %l;
+
+ if (@l > 1 && !$auto) {
+ $msg = _("One of the following packages is needed:");
+ my $n;
+ if ($X) {
+ `gchooser "$msg" @l`;
+ $n = $? >> 8 || die;
+ } else {
+ print SAVEOUT "$msg\n";
+ my $i = 0; foreach (@l) { print SAVEOUT " ", ++$i, "- $_\n"; }
+ while (1) {
+ print SAVEOUT _("What is your choice? (1-%d) ", $i);
+ $n = <STDIN>;
+ 1 <= $n && $n <= $i and last;
+ print SAVEOUT _("Sorry, bad choice, try again\n");
+ }
+ }
+ $l = $l[$n - 1];
+ }
+ closure_deps($to_install, $l);
+ }
+ }
+}
+
+#- compare a version string.
+sub version_compare {
+ my ($a, $b) = @_;
+ local $_;
+
+ while ($a && $b) {
+ my ($sb, $sa) = map { $1 if $a =~ /^\W*\d/ ? s/^\W*0*(\d+)// : s/^\W*(\D+)// } ($b, $a);
+ $_ = length($sa) cmp length($sb) || $sa cmp $sb and return $_;
+ }
+}
+sub le_version {
+ my $cmp = version_compare($_[0][0], $_[1][0]);
+ return $cmp < 0 || $cmp == 0 && version_compare($_[0][1], $_[1][1]) < 0;
+}
+
+
+
+sub message { $X ? `gmessage -default Ok -buttons Ok "$_[0]"` : print SAVEOUT "$_[0]\n"; }
+sub member($@) { my $e = shift; foreach (@_) { $e eq $_ and return 1 } 0 }
+sub uniq { my %l; @l{@_} = (); keys %l }
+sub difference2(\@\@) { my %l; @l{@{$_[1]}} = (); grep { !exists $l{$_} } @{$_[0]} }
+sub _ { my $s = shift @_; sprintf translate($s), @_ }
+sub translate { $I18N{$_[0]} || $_[0]; }
+
+sub untaint {
+ my @r = ();
+ foreach (@_) {
+ /(.*)/;
+ push @r, $1;
+ }
+ @r == 1 ? $r[0] : @r
+}
+
+sub load_po {
+ my ($from, $to, $state, $fuzzy);
+ local *F; open F, "/usr/share/locale/$_[0]/LC_MESSAGES/urpmi.po" or return;
+ foreach (<F>) {
+ /^msgstr/ and $state = 1;
+ /^msgid/ && !$fuzzy and $state = 2;
+
+ if (/^(#|$)/ && $state != 3) {
+ $state = 3;
+ s/\\n/\n/g foreach $from, $to;
+ $I18N{$from} = $to if $from;
+ $from = $to = '';
+ }
+ $to .= (/"(.*)"/)[0] if $state == 1;
+ $from .= (/"(.*)"/)[0] if $state == 2;
+
+ $fuzzy = /^#, fuzzy/;
+ }
+}