#!/usr/bin/perl ################################################################################ # isodiff # # # # Copyright (C) 2002 MandrakeSoft # # # # Goneri Le Bouder <glebouder@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 strict; use RPM::Header; use File::Temp qw/ tempfile tempdir /; my $version; my $old_iso; my $new_iso; my %hachage_new; my %hachage_old; my %changelog; my @new_pkg; my @newrelease_pkg; my @updated_pkg; my @removed_pkg; my $i; my $html_output; my $new_tmpdir; my $old_tmpdir; my $df_new_tmpdir; my $df_old_tmpdir; $version="0.1"; sub give_tmp{ $_[0] = tempdir( ); } sub argument { my $arg; if ( $#ARGV == 2 ) { $arg = shift (@ARGV); if ( $arg eq "--html" ) { $html_output = 1; } else { &usage; } } if ( $#ARGV == 1 ) { $new_iso = shift (@ARGV); $old_iso = shift (@ARGV); } else { &usage; } } sub usage { print "Iso diff $version\n"; print "Usage : isodiff [OPTION] [NEW_ISO] [OLD_ISO]\n"; print " -h --help : help message\n"; print " --html : html output\n"; print "\nexemple : isodiff --html new-release.iso old-release.iso > ../test.html\n"; exit 1; } ###Mount################### sub mount { my @cmd_line; my $stat; if ( @_ != 2 ) { print "&mount usage : [iso name] , [mount_point]\n"; exit 0; } @cmd_line = ( "mount", "-t", "iso9660", "-o", "nodev,nosuid,ro,loop", "$_[0]", "$_[1]" ); if ( $stat = system(@cmd_line) ) { print STDERR "mount failed, status=" . ( $stat >> 8 ) . "\n" . " command was: @cmd_line\n"; } else { } } ###Umount################### sub umount { system "umount $_[0]"; system "umount $_[1]"; } ###Cleanage################# sub cleanage { rmdir $_[0]; rmdir $_[1]; } ###Listage##################### sub listage { my @mdk_dir; my $i; my $j; my $fichier_rpm; my $headers; my @list_rpm; my @tableau_new; my @tableau_old; if ( @_ != 2 ) { print "&listage : usage [new_iso] [old_iso]\n"; exit 0; } ####New########################## $i = undef; @mdk_dir = undef; open( FICHIER, "<$new_tmpdir" . "/Mandrake/base/hdlists" ) or die "can't load hdlists $_[0]"; $i = 0; while (<FICHIER>) { chomp; if (/\S+\s+(\S+)\s+\S+\s+\S+\s+\S+/) { $mdk_dir[$i] = $1; $i++; } } close FICHIER or die "can't close hdlists of $_[0]"; foreach (@mdk_dir) { opendir( DOSSIER, $new_tmpdir . "/" . $_ ) or die "can't open $!"; while ( defined( $fichier_rpm = readdir(DOSSIER) ) ) { next unless $fichier_rpm =~ /\.rpm$/; $headers = new RPM::Header $new_tmpdir . "/" . $_ . "/" . $fichier_rpm; $hachage_new{ $headers->{name} } = [ $headers->{version}, $headers->{release}, $headers->{description}, $headers->{CHANGELOGTEXT} ]; } closedir DOSSIER or die "can't open $!"; } ####Old########################## open( FICHIER, "<$old_tmpdir/" . "/Mandrake/base/hdlists" ) or die "can't open $!"; $i = undef; @mdk_dir = undef; $i = 0; while (<FICHIER>) { chomp; if (/\S+\s+(\S+)\s+\S+\s+\S+\s+\S+/) { $mdk_dir[$i] = $1; $i++; } } close FICHIER or die "can't close $!"; foreach (@mdk_dir) { opendir( DOSSIER, $old_tmpdir . "/" . $_ ) or die "can't open $!"; while ( defined( $fichier_rpm = readdir(DOSSIER) ) ) { next unless $fichier_rpm =~ /\.rpm$/; $headers = new RPM::Header $old_tmpdir . "/" . $_ . "/" . $fichier_rpm; $hachage_old{ $headers->{name} } = [ $headers->{version}, $headers->{release}, $headers->{description}, $headers->{CHANGELOGTEXT} ]; } closedir(DOSSIER) or die "can't close $!"; } ####Compar########################## ### foreach ( keys %hachage_old ) { push @list_rpm, $_; } foreach ( keys %hachage_new ) { if ( !( $hachage_old{$_} ) ) { push @list_rpm, $_; } } ### $i = undef; foreach $i ( sort @list_rpm ) { } foreach $i ( sort @list_rpm ) { if ( defined @{ $hachage_new{$i} } ) { @tableau_new = @{ $hachage_new{$i} }; } else { @tableau_new = undef; } if ( defined @{ $hachage_old{$i} } ) { @tableau_old = @{ $hachage_old{$i} }; } else { @tableau_old = undef; } if ( !( $tableau_new[0] eq $tableau_old[0] ) ) { if ( !( $tableau_old[0] ) ) { push @new_pkg, $i; } if ( !( $tableau_new[0] ) ) { push @removed_pkg, $i; } if ( ( $tableau_new[0] ) && ( $tableau_old[0] ) ) { push @newrelease_pkg, $i; } } elsif ( !( $tableau_new[1] eq $tableau_old[1] ) ) { foreach ( reverse( @{ $tableau_old[3] } .. @{ $tableau_new[3] } ) ) { if ( $html_output == 1 ) { ${ @{ $tableau_new[3] } }[ @{ $tableau_new[3] } - $_ ] =~ s/([<])/\</g; ${ @{ $tableau_new[3] } }[ @{ $tableau_new[3] } - $_ ] =~ s/([>])/\>/g; push @{ $changelog{$i} }, ${ @{ $tableau_new[3] } }[ @{ $tableau_new[3] } - $_ ] . "<br>\n"; ### Si l'on veut afficher l'auteur de la mise a jour du rpm dans les logs #"<i>".${ @{ $tableau_new[4] } }[ @{ $tableau_new[3] } - $_ ] . "</i><br>\n" ### } else { push @{ $changelog{$i} }, ${ @{ $tableau_new[3] } }[ @{ $tableau_new[3] } - $_ ] . "\n" . ${ @{ $tableau_new[4] } }[ @{ $tableau_new[3] } - $_ ] . "\n"; } } push @updated_pkg, $i; } } } sub ascii_output { print "New version of packages:\n @new_pkg \n\n"; print "Removed Packages: @removed_pkg \n\n"; print "New Releases:\n @newrelease_pkg \n\n"; print "Updated packages:\n @updated_pkg \n\n"; print "Changelog of the updated packages:\n"; foreach (@updated_pkg) { print "$_:\n"; print @{ $changelog{$_} }; } print "\n"; } sub html_output { my $i; print " <html> <head> <title>isodiff change : $old_iso to $new_iso</title> <meta http-equiv=\"content-type\" content=\"text/html; charset=ISO-8859-1\"> <base href=\"about:blank\"> </head> <body text=\"#000000\" bgcolor=\"#ffffff\" link=\"#000099\" vlink=\"#990099\" alink=\"#000099\"> <h2><b>$old_iso to $new_iso :</b></h2> <br> <br> <b>New version of packages :</b><br>"; foreach $i (@new_pkg) { print "$i-${$hachage_new{$i}}[0]-${$hachage_new{$i}}[1]<br>\n"; } print "<br> <b>Removed packages :</b><br>\n"; foreach $i (@removed_pkg) { print "$i-${$hachage_old{$i}}[0]-${$hachage_old{$i}}[1]<br>\n"; } print "<br> <b>New release :</b><br>\n"; foreach $i (@newrelease_pkg) { print "$i-${$hachage_new{$i}}[0]-${$hachage_new{$i}}[1]<br>\n"; } print "<br> <b>Updated packages :</b><br>\n"; foreach $i (@updated_pkg) { print "$i-${$hachage_new{$i}}[0]-${$hachage_new{$i}}[1]<br>\n"; } print "<br>Changelog of the updated packages:<br> <table cellpadding=\"2\" cellspacing=\"2\" border=\"0\" width=\"600\" bgcolor=\"Silver\"> <tbody> <tr> <td valign=\"top\">"; foreach $i (@updated_pkg) { print "<b>$i</b><br>\n"; print @{ $changelog{$i} }; print "<br>"; } print "</td> </tr> </tbody> </table> <br> <br> <br> </body> </html>" } &give_tmp($new_tmpdir); &give_tmp($old_tmpdir); mkdir( $new_tmpdir . $new_tmpdir, 700 ); mkdir( $old_tmpdir . $old_tmpdir, 700 ); &argument; &mount( $new_iso, $new_tmpdir ); &mount( $old_iso, $old_tmpdir ); &listage( $new_iso, $old_iso ); if ( $html_output == 1 ) { &html_output; } else { &ascii_output; } &umount ($new_tmpdir, $old_tmpdir); &cleanage ($new_tmpdir,$old_tmpdir);