#!/usr/bin/perl ################################################################################ # Mdkupdate # # # # Copyright (C) 2002 MandrakeSoft # # # Daouda Lo # # # # This program is free software; you can redistribute it and/or modify # # it under the terms of the GNU General Public License Version 2 as # # published by the Free Software Foundation. # # # # This program is distributed in the hope that it will be useful, # # but WITHOUT ANY WARRANTY; without even the implied warranty of # # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # # GNU General Public License for more details. # # # # You should have received a copy of the GNU General Public License # # along with this program; if not, write to the Free Software # # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # ################################################################################ use POSIX; use Digest::MD5 qw(md5 md5_hex md5_base64); use HTTP::Request; use HTTP::Request::Common; use LWP::UserAgent; use Net::HTTPS; #for https connections use MIME::Base64 qw(encode_base64); use lib qw(/usr/lib/libDrakX); use common; BEGIN { unshift @::textdomains, 'mdkupdate' } require_root_capability(); my $logfile = "/var/log/mdkupdate.log"; my $conffile = "/root/.mdkupdate"; my $onlineUrl = "https://www.mandrakeonline.net/"; my %url; foreach (qw(online_dif online_update online3_RemoteAction)) { $url->{$_} = $onlineUrl . $_ . '.php' } my $rpms_rep = "/root/tmp/"; my $VERSION = "0.17"; my $security = grep { /^-?-security$/ } @ARGV; my $update = grep { /^-?-update$/ } @ARGV; my ($scheduled, $noscheduled); sub usage { print STDERR N("mdkupdate version %s Copyright (C) 2002 MandrakeSoft. This is free software and may be redistributed under the terms of the GNU GPL. usage: ", $VERSION) . N(" --help - print this help message. ") . N(" --auto - Mdkupdate launched automatically. ") . N(" --applet - launch MandrakeUpdate. ") . N(" --update - Update keys "); exit(0); } my ($opt) = @ARGV; @ARGV == 1 && ($opt eq '--auto' || $opt eq '--security' || $opt eq '--applet' || $opt eq '--help') or usage(); -s $conffile or die N("No $conffile file found. Run mdkonline wizard first"); my %o = getVarsFromSh($conffile); if ($o{LOGIN} && $o{PASS} && $o{LOGIN} !~ /\s+/ && $o{PASS} !~ /\s+/) { my $MandrakeUpdateURL = $url->{online3_RemoteAction} . '?action=ScheduledRPM' . '&log=' . $o{LOGIN} . '&pass=' . $o{PASS} . '&host=' . $o{MACHINE} . '&key=' . $o{CURRENTKEY}; my $resp = getFromURL($MandrakeUpdateURL); my $contents = $resp->content; print " \n\n ***** Response from Online3_RemoteAction is : \n $contents \n end update_rpms answer **********\n\n"; if ($resp->is_success) { $ret = ($contents =~ /TRUE/) ? 0 : -1; } else { log_i(N("Connection problem")."\n" . N("MandrakeUpdate could not contact the site, we will try again.")); } } else { $ret = -1; } if(!$ret) { my $c2h = splitContents($contents); if ($c2h->{torf} eq "TRUE" && $c2h->{OLDKEY} && $c2h->{NEWKEY}) { updateConf($c2h->{OLDKEY}, $c2h->{NEWKEY}) } if ($c2h->{FTP}) { addMedia($c2h->{FTP}) } $scheduled = join(',',@{$c2h->{sched}}); $noscheduled = join(',',@{$c2h->{nosched}}); if ($opt eq '--applet') { system "MandrakeUpdate","--media=mdkupdate","--pkg-sel=$scheduled","--pkg-nosel=$nosheduled"; } elsif ($opt eq '--auto') { $o{AUTO} eq 'TRUE' and autoInstallRpms($c2h->{sched}); } rpm_qa("/root/rpm_qa_installed_after"); my %new = getVarsFromSh($conffile); if (! -s "/root/.mdkupdate.rpms" || $update) { #- send configuration and get back key to use... $new{CURRENTKEY} = send_config($new{LOGIN},$new{PASS},$new{MACHINE}); delete $new{OLDKEY}; #- save back keys. setVarsInSh($conffile, \%new); } else { #- this can safely be ignored if new configuration is sent. send_rpm_dif($new{LOGIN},$new{PASS},$new{MACHINE},$new{OLDKEY}); } clean_dir(); } sub splitContents { my $cont = shift; my ($elem, $s); $s = [ split /\n/, $cont ]; $elem->{torf} = $s->[0]; if ($elem->{torf} eq 'TRUE') { ($elem->{torf},$elem->{OLDKEY},$elem->{NEWKEY},$elem->{FTP}) = splice(@$s,0,4); ($elem->{sched},$elem->{nosched}) = partition { $_ =~/i586$/ } @$s; } $elem } ################################################################################ # Taken from mdkonline to perform complete update of rpm list (by diff), it has # been decided to do exactly what mdkonline does the first time to update the db. ################################################################################ sub report_config { my ($file) = @_; sub header { " ******************************************************************************** * $_[0] ********************************************************************************"; } open (FILE,"> $file") || die "Couldn't open $file : $!"; map { chomp; print FILE "$_\n" } header("scsi"), cat_("/proc/scsi/scsi"), header("lsmod"), cat_("/proc/modules"), header("cmdline"), cat_("/proc/cmdline"), header("pcmcia: stab"), cat_("$prefix/var/lib/pcmcia/stab") || cat_("$prefix/var/run/stab"), header("usb"), cat_("/proc/bus/usb/devices"), header("partitions"), cat_("/proc/partitions"), header("cpuinfo"), cat_("/proc/cpuinfo"), header("install.log"), cat_("$prefix/root/drakx/install.log"), header("fstab"), cat_("$prefix/etc/fstab"), header("lilo.conf"), cat_("$prefix/etc/lilo.conf"), header("menu.lst"), cat_("$prefix/boot/grub/menu.lst"), header("/etc/modules.conf"), cat_("$prefix/etc/modules.conf"), header("rpm -qa"), join ('', sort `rpm -qa`), header("mandrake version"), cat_('/etc/redhat-release'); close(FILE); } sub getFromURL { my ($link) = @_; my $ua = LWP::UserAgent->new; $ua->agent("MdkUpdateAgent/$VERSION" . $ua->agent); $ua->env_proxy; my $request = HTTP::Request->new(GET => $link); my $response = $ua->request($request); $response } sub send_config { # When we arrive here, we're sure the login/passwd is correct my ($login, $passwd, $box_name) = @_; # print STDERR "Sending config\n"; my $result = -1; report_config("/root/$login.$passwd.$box_name.online.log"); `/usr/bin/bzip2 \\\-9 \\\-f /root/$login.$passwd.$box_name.online.log`; # Turn the binary file into a uuencoded ascii file open (FILE, "/root/$login.$passwd.$box_name.online.log.bz2") or die "$!"; my ($chunk, $buffer); while (read(FILE, $chunk, 60*57)) { $buffer .= $chunk; } close (FILE); open (FILEOUT, "> /root/$login.$passwd.$box_name.online.log.bz2.uue") or die "$!"; print FILEOUT encode_base64($buffer); close (FILEOUT); my $ua = LWP::UserAgent->new; $ua->agent("MdkOnlineAgent/$VERSION" . $ua->agent); $ua->env_proxy; my $response = $ua->request(POST 'https://www.mandrakeonline.net/wizard.php', Content_Type => 'form-data', Content => [submit => "upload_wizard", wizard => ["/root/$login.$passwd.$box_name.online.log.bz2.uue"] ]); # Check the outcome of the response #print "REPONSE: ".$response->content."\n"; if ($response->is_success) { $result = ($response->content =~ /TRUE(.*)/) ? 0 : -1; #print("key is $1\n"); $key = $1; #- update local copy now. unlink "/root/.mdkupdate.rpms"; rename "/root/rpm_qa_installed_after", "/root/.mdkupdate.rpms"; } else { # pb with the connection ? $result = -1; } unlink "/root/$login.$passwd.$box_name.online.log.bz2"; unlink "/root/$login.$passwd.$box_name.online.log.bz2.uue"; $result == 0 && $key; } ################################################################################ sub autoInstallRpms { my ($pkgs) = shift; my @pkg; push(@pkg, $_ . '.rpm') foreach @{$pkgs}; updatePkgs(@pkg); } sub updateConf { my ($oldkey, $newkey) = @_; my %l = getVarsFromSh $conffile; setVarsInSh($conffile, { OLDKEY => $oldkey, CURRENTKEY => $newkey, VER => $l{VER}, MACHINE => $l{MACHINE}, PASS => $l{PASS}, LOGIN => $l{LOGIN}, AUTO => $l{AUTO} }); } sub addMedia { my $mirror = shift; my $r = getRelease(); my $fullpath2mir = "ftp://" . "$mirror". "/$r" . "/RPMS" . "/" ; eval { system "/usr/sbin/urpmi.removemedia", "mdkupdate"; system "/usr/sbin/urpmi.addmedia", "--update", "mdkupdate", $fullpath2mir, "with ../base/hdlist.cz"; }; $@ and die "Problem adding Update Media with urpmi"; } sub getRelease() { my $release = cat_('/etc/mandrake-release') =~ /release\s+(\S+)/; $release } sub updatePkgs { my (@str) = @_; @str or return; eval { system "/usr/sbin/urpmi", "--auto", "--media", "mdkupdate", map { /^(.*)\.rpm$/ && $1 } @str; $? == 0 or die N("Unable to update packages from mdkupdate medium.\n"); }; $@ and die "Problem upgrading with urpmi"; } sub send_rpm_dif { my ($login,$password,$box_name,$oldkey) =@_; #`sdiff -s /root/rpm_qa_installed_after /root/rpm_qa_installed_before >/root/$login.$password.$box_name.$oldkey.dif`; `sdiff -s /root/rpm_qa_installed_after /root/.mdkupdate.rpms >/root/$login.$password.$box_name.$oldkey.dif`; -s "/root/$login.$password.$box_name.$oldkey.dif" or die N("System is up to date"); my $ua = LWP::UserAgent->new; $ua->agent("MdkOnlineAgent/$VERSION" . $ua->agent); $ua->env_proxy; my $response = $ua->request(POST "https://www.mandrakeonline.net/online_dif.php", Content_Type => 'form-data', Content => [submit => "upload_dif", dif_file => ["/root/$login.$password.$box_name.$oldkey.dif"] ]); #- update .mdkupdate.rpms with newer version just sent. if ($response->content =~ /TRUE/) { unlink "/root/.mdkupdate.rpms"; rename "/root/rpm_qa_installed_after", "/root/.mdkupdate.rpms"; } else { print "REPONSE: " . $response->content . "\n"; } } sub clean_dir() { system("rm -f /root/*.dif /root/rpm_qa_installed_before /root/rpm_qa_installed_after"); } sub rpm_qa { my ($file) = @_; open (FILE,"> $file") || die "Couldn't open $file : $!"; map { chomp; print FILE "$_" } join('', sort `rpm -qa`); close FILE; } sub log_i { local *LOG; open LOG, ">>/var/log/mdkupdate.log" or die "can't output to log file\n"; print LOG @_; close LOG; } sub fatal { my ($comment)=@_; printf STDERR "%s\n", $comment; exit($_[0]); }