#!/usr/bin/perl
################################################################################
# Mdkupdate                                                                    # 
#                                                                              #
# Copyright (C) 2002-2004 Mandrakesoft                                         #
#                                                                              #
# Daouda Lo <daouda@mandrakesoft.com>                                          #
#                                                                              #
# 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 lib qw(/usr/lib/libDrakX /usr/lib/libDrakX/drakfirsttime);
use common;
use mdkonline;

BEGIN { unshift @::textdomains, 'mdkupdate' }

require_root_capability();

my $confdir = '/root/.MdkOnline';
my $conffile = "$confdir/mdkupdate";

my $onlineUrl = "https://www.mandrakeonline.net/";
my %url;
foreach (qw(online_dif online_update online3_RemoteAction wizard)) {
    $url->{$_} = $onlineUrl . $_ . '.php'
}
my $rpms_rep = "/root/tmp/";
my $VERSION = "1.0";
my $YEARS = "2002-2004";

#for compatibilities
mkdir_p($confdir) if !-d $confdir;
-e '/root/.mdkupdate' and system("mv", "/root/.mdkupdate", $conffile);

my ($scheduled, $noscheduled);

sub usage {
    print STDERR N("mdkupdate version %s
Copyright (C) %s Mandrakesoft.
This is free software and may be redistributed under the terms of the GNU GPL.

usage:
", $VERSION, $YEARS) . N("  --help         - print this help message.
") . N("  --auto         - Mandrakeupdate launched automatically.
") . N("  --applet       - launch Mandrakeupdate.
") . N("  --update       - Update keys
");
    exit(0);
}

my ($opt) = @ARGV;
@ARGV == 1 && ($opt eq '--auto' || $opt eq '--applet') or usage();

-s $conffile or die N("No %s file found. Run mdkonline wizard first", $conffile);

my %o = getVarsFromSh($conffile);
if ($o{LOGIN} && $o{PASS} && $o{LOGIN} !~ /\s+/ && $o{PASS} !~ /\s+/) {
    my $u;
    my $MandrakeUpdateURL = $url->{online3_RemoteAction} . '?action=ScheduledRPM' . '&log=' . $o{LOGIN} . '&pass=' . $o{PASS} . '&host=' . $o{MACHINE} . '&key=' . $o{CURRENTKEY};
    my $resp = mdkonline::get_from_URL($MandrakeUpdateURL);
    my $contents = $resp->content;
    #print "CONTENTS = $contents \n";
    if ($resp->is_success) {
	if ($contents =~ /TRUE/) { $u = 10 } elsif ($contents =~ m/(\d+)/) { $u = sprintf("%d", $1) } else { $u = 83 };
	my $action = {
		      10 => sub {
			  my $c2h = split_contents($contents);
			  #printf("\nCONTENTS = $contents \n torf = %s\n OLDKEY = %s = %s \n NEWKEY = %s \n FTP = %s\n", $c2h->{torf}, $c2h->{OLDKEY}, $o{CURRENTKEY}, $c2h->{NEWKEY}, $c2h->{FTP} );
			  if ($c2h->{torf} eq "TRUE" && $c2h->{OLDKEY} && $c2h->{NEWKEY}) { update_conf($c2h->{OLDKEY}, $c2h->{NEWKEY}) }
			  if ($c2h->{FTP}) { 
			      # for debugging purpose
			      printf("FTP = %s\n", $c2h->{FTP});
			      #$c2h->{FTP} = 'ftp://ftp.lip6.fr/pub/linux/distributions/mandrake/updates';
			      add_media($c2h->{FTP})
			  }
			  $scheduled = join(',', @{$c2h->{sched}});
			  $noscheduled = join(',', @{$c2h->{nosched}}); $noscheduled =~ s/\.rpm//g;
			  #printf "SCHEDULED = $scheduled\nNOSCHEDULED = $noscheduled\n";
			  if ($opt eq '--applet') {
			      system "MandrakeUpdate", "--no-confirmation", "--media=mdkupdate", "--pkg-sel=$scheduled", "--pkg-nosel=$noscheduled";
			  } elsif ($opt eq '--auto') {
			      $o{AUTO} eq 'TRUE' and auto_install_rpms($c2h->{sched});
			  }
			  rpm_qa("$confdir/rpm_qa_installed_after");
			  my %new = getVarsFromSh($conffile);
			  if (! -s "$confdir/mdkupdate.rpms" || $opt eq '--auto') {
			      #- send configuration and get back key to use...
			      my $r;
			      ($r, $new{CURRENTKEY}) = send_conf_update($new{LOGIN}, $new{PASS}, $new{MACHINE});
			      if ($r eq 'TRUE') { delete $new{OLDKEY}; 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();
		      },
		      80 => sub { 
			  log::l("[mdkupdate] Client password does not match in database")
		      },
		      81 => sub {
			  log::l("[mdkupdate] Bad Authentification key. Please rerun mdkonline wizard")
		      },
		      82 => sub {
			  log::l("[mdkupdate] No active Online service found for this host.")
		      },
		      83 => sub {
			  log::l("[mdkupdate] Unknown problem, better relaunch mdkonline wizard or check connexion")
		      }
		     };
	$action->{$u}->();
    } else {
	log::l(N("Connection problem")."\n" . N("Mandrakeupdate could not contact the site, we will try again."));
    }
} else {
    $ret = -1; 
}
sub split_contents {
    my $cont = shift;
    my ($elem, $s);
    $s = [ split /\n/, $cont ];
    $elem->{torf} = $s->[0];
    if ($elem->{torf} eq 'TRUE') {
	($elem->{torf}, $elem->{NEWKEY}, $elem->{OLDKEY}, $elem->{FTP}) = splice(@$s, 0, 4);
	($elem->{sched}, $elem->{nosched}) = partition { /(i586|ppc|ia64|noarch|x86_64|amd64|ppc64)$/ } @$s;
    }
    $elem
}
sub auto_install_rpms {
    my ($pkgs) = shift;
    my @pkg;
    push(@pkg, $_ . '.rpm') foreach @$pkgs;
    update_pkgs(@pkg);
}
sub update_conf {
    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 add_media {
    my $mirror = shift;
    my ($r) = mdkonline::get_release();
    my $fullpath2mir = "ftp://" . $mirror . "/$r" . "/RPMS" . "/";
    eval {
	system "/usr/sbin/urpmi.removemedia", "mdkupdate";
	system "/usr/sbin/urpmi.addmedia", "--update", "mdkupdate", $fullpath2mir, "with", "../base/synthesis.hdlist.cz";
    };
    $@ and die "Problem adding Update Media with urpmi";
}
sub update_pkgs {
    @_ or return;
    eval {
	system "/usr/sbin/urpmi", "--auto", "--media", "mdkupdate", map { /^(.*)\.rpm$/ && $1 } @_;
	$? == 0 or die N("Unable to update packages from mdkupdate medium.\n");
    };
    $@ and die "Problem upgrading with urpmi";
}
sub send_conf_update {
    my ($login, $password, $boxname) = @_;
    mdkonline::report_config("$confdir/$login.$password.$boxname.online.log");
    my $tag = { submit => 'upload_wizard', wizard => [ "$confdir/$login.$password.$boxname.online.log.bz2.uue" ] };
    my ($res, $key) = mdkonline::send_config($url->{wizard}, $tag);
    ($res, $key)
}
sub send_rpm_dif {
    my ($login, $password, $boxname, $oldkey) = @_;
    `sdiff -s $confdir/rpm_qa_installed_after $confdir/mdkupdate.rpms > $confdir/$login.$password.$boxname.$oldkey.dif`;
    -s "$confdir/$login.$password.$boxname.$oldkey.dif" or die N("No diff found");
    my $tag = { submit => "upload_dif", dif_file => [ "$confdir/$login.$password.$boxname.$oldkey.dif" ] };
    my ($res, $key) = mdkonline::send_config($url->{online_dif}, $tag);
    #- update mdkupdate.rpms with newer version just sent.
    if ($res eq 'TRUE') {
	unlink "$confdir/mdkupdate.rpms";
	rename "$confdir/rpm_qa_installed_after", "$confdir/mdkupdate.rpms";
    } else {
	log::l(N("Connection problem")."\n" . N("Mandrakeupdate could not upload the diff files. Send a mail to support [at] mandrakeonline [dot] net"));
	return
    }
}

sub clean_dir() {
    system("rm -f $confdir/*log.bz2 $confdir/*log.bz2.uue $confdir/*.dif $confdir/rpm_qa_installed_before $confdir/rpm_qa_installed_after");    
}

sub rpm_qa {
    my ($file) = @_;
    output($file, chomp_(join('', sort(`rpm -qa`))));
}