build-compare/rpm-check.sh

482 lines
15 KiB
Bash
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#! /bin/bash
#
# Copyright (c) 2009, 2010 SUSE Linux Product GmbH, Germany.
# Licensed under GPL v2, see COPYING file for details.
#
# Written by Michael Matz and Stephan Coolo
# Enhanced by Andreas Jaeger
FUNCTIONS=${0%/*}/functions.sh
check_all=
case $1 in
-a | --check-all)
check_all=1
shift
esac
if test "$#" != 2; then
echo "usage: $0 [-a|--check-all] old.rpm new.rpm"
exit 1
fi
source $FUNCTIONS
oldrpm=`readlink -f $1`
newrpm=`readlink -f $2`
if test ! -f $oldrpm; then
echo "can't open $oldrpm"
exit 1
fi
if test ! -f $newrpm; then
echo "can't open $newrpm"
exit 1
fi
#usage unjar <file>
function unjar()
{
local file
file=$1
if [[ $(type -p fastjar) ]]; then
UNJAR=fastjar
elif [[ $(type -p jar) ]]; then
UNJAR=jar
elif [[ $(type -p unzip) ]]; then
UNJAR=unzip
else
echo "ERROR: jar, fastjar, or unzip is not installed (trying file $file)"
exit 1
fi
case $UNJAR in
jar|fastjar)
# echo jar -xf $file
${UNJAR} -xf $file
;;
unzip)
unzip -oqq $file
;;
esac
}
# list files in directory
#usage unjar_l <file>
function unjar_l()
{
local file
file=$1
if [[ $(type -p fastjar) ]]; then
UNJAR=fastjar
elif [[ $(type -p jar) ]]; then
UNJAR=jar
elif [[ $(type -p unzip) ]]; then
UNJAR=unzip
else
echo "ERROR: jar, fastjar, or unzip is not installed (trying file $file)"
exit 1
fi
case $UNJAR in
jar|fastjar)
${UNJAR} -tf $file
;;
unzip)
unzip -l $file
;;
esac
}
filter_disasm()
{
sed -e 's/^ *[0-9a-f]\+://' -e 's/\$0x[0-9a-f]\+/$something/' -e 's/callq *[0-9a-f]\+/callq /' -e 's/# *[0-9a-f]\+/# /' -e 's/\(0x\)\?[0-9a-f]\+(/offset(/' -e 's/[0-9a-f]\+ </</' -e 's/^<\(.*\)>:/\1:/' -e 's/<\(.*\)+0x[0-9a-f]\+>/<\1 + ofs>/'
}
cmp_spec $1 $2
RES=$?
case $RES in
0)
exit 0
;;
1)
exit 1
;;
2)
;;
*)
echo "Wrong exit code!"
exit 1
;;
esac
file1=`mktemp`
file2=`mktemp`
dir=`mktemp -d`
unrpm $oldrpm $dir/old
unrpm $newrpm $dir/new
cd $dir
dfile=`mktemp`
diff_two_files()
{
if ! cmp -s old/$file new/$file; then
echo "$file differs ($ftype)"
hexdump -C old/$file > $file1
hexdump -C new/$file > $file2
diff -u $file1 $file2 | head -n 200
return 1
fi
return 0
}
check_single_file()
{
local file=$1
case $file in
*.spec)
sed -i -e "s,Release:.*$release1,Release: @RELEASE@," old/$file
sed -i -e "s,Release:.*$release2,Release: @RELEASE@," new/$file
;;
*.exe.mdb|*.dll.mdb)
# Just debug information, we can skip them
echo "$file skipped as debug file."
return 0
;;
*.a)
echo "$file is .a"
flist=`ar t new/$file`
pwd=$PWD
fdir=`dirname $file`
cd old/$fdir
ar x `basename $file`
cd $pwd/new/$fdir
ar x `basename $file`
cd $pwd
for f in $flist; do
if ! check_single_file $fdir/$f; then
return 1
fi
done
return 0
;;
*.tar|*.tar.bz2|*.tar.gz|*.tgz|*.tbz2)
flist=`tar tf new/$file`
pwd=$PWD
fdir=`dirname $file`
cd old/$fdir
tar xf `basename $file`
cd $pwd/new/$fdir
tar xf `basename $file`
cd $pwd
local ret=0
for f in $flist; do
if ! check_single_file $fdir/$f; then
ret=1
if test -z "$check_all"; then
break
fi
fi
done
return $ret
;;
*.zip|*.jar)
cd old
unjar_l ./$file |sort > flist
sed -i -e "s, [0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9] , date ," flist
cd ../new
unjar_l ./$file |sort> flist
sed -i -e "s, [0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9] , date ,; " flist
cd ..
if ! cmp -s old/flist new/flist; then
echo "$file has different file list"
diff -u old/flist new/flist
return 1
fi
flist=`grep date new/flist | sed -e 's,.* date ,,'`
pwd=$PWD
fdir=`dirname $file`
cd old/$fdir
unjar `basename $file`
cd $pwd/new/$fdir
unjar `basename $file`
cd $pwd
local ret=0
for f in $flist; do
if test -f new/$fdir/$f && ! check_single_file $fdir/$f; then
ret=1
if test -z "$check_all"; then
break
fi
fi
done
return $ret;;
*.pyc|*.pyo)
perl -E "open fh, '+<', 'old/$file'; seek fh, 3, SEEK_SET; print fh '0000';"
perl -E "open fh, '+<', 'new/$file'; seek fh, 3, SEEK_SET; print fh '0000';"
;;
*.bz2)
bunzip2 -c old/$file > old/${file/.bz2/}
bunzip2 -c new/$file > new/${file/.bz2/}
check_single_file ${file/.bz2/}
return $?
;;
*.gz)
gunzip -c old/$file > old/${file/.gz/}
gunzip -c new/$file > new/${file/.gz/}
check_single_file ${file/.gz/}
return $?
;;
*png)
# Try to remove timestamps, only if convert from ImageMagick is installed
if [[ $(type -p convert) ]]; then
convert old/$file +set date:create +set date:modify old/${file/.png/_n.png}
convert old/$file +set date:create +set date:modify new/${file/.png/_n.png}
if ! cmp -s old/${file/.png/_n.png} new/${file/.png/_n.png}; then
echo "$file differs ($ftype)"
hexdump -C old/${file/.png/_n.png} > $file1
hexdump -C new/${file/.png/_n.png} > $file2
diff -u $file1 $file2 | head -n 20
return 1
fi
return 0
fi
;;
/usr/share/locale/*/LC_MESSAGES/*.mo|/usr/share/locale-bundle/*/LC_MESSAGES/*.mo)
for f in old/$file new/$file; do
sed -i -e "s,POT-Creation-Date: ....-..-.. ..:..+....,POT-Creation-Date: 1970-01-01 00:00+0000," $f
done
;;
/usr/share/doc/packages/*/*.html|\
/usr/share/doc/kde/HTML/*/*/*.html|/usr/share/doc/*/html/*.html)
for f in old/$file new/$file; do
# texi2html output, e.g. in kvm, indent, qemu
sed -i -e "s|^<!-- Created on .*, 20.. by texi2html .\...|<!-- Created on August 7, 2009 by texi2html 1.82|" $f
sed -i -e 's|^ *This document was generated by <em>Autobuild</em> on <em>.*, 20..</em> using <a href="http://www.nongnu.org/texi2html/"><em>texi2html .\...</em></a>.$| This document was generated by <em>Autobuild</em> on <em>August 7, 2009</em> using <a href="http://www.nongnu.org/texi2html/"><em>texi2html 1.82</em></a>.|' $f
# doxygen docu, e.g. in libssh and log4c
sed -i -e 's|Generated on ... ... [0-9]* [0-9]*:[0-9][0-9]:[0-9][0-9] 20[0-9][0-9] for |Generated on Mon May 10 20:45:00 2010 for |' $f
# Generated on Sat Aug 14 2010 16:49:48 for libssh
sed -i -e 's|Generated on ... ... [0-9]* 20[0-9][0-9] [0-9]*:[0-9][0-9]:[0-9][0-9] for |Generated on Mon May 10 20:45:00 2010 for |' $f
done
;;
/usr/share/javadoc/*.html |\
/usr/share/javadoc/*/*.html|/usr/share/javadoc/*/*/*.html)
# There are more timestamps in html, so far we handle only some primitive versions.
for f in old/$file new/$file; do
# Javadoc:
sed -i -e "s,^<!-- Generated by javadoc (build [0-9._]*) on ... ... .. ..:..:.. UTC .... -->,^<!-- Generated by javadoc (build 1.6.0_0) on Sun Jul 01 00:00:00 UTC 2000 -->," $f
sed -i -e 's|^<!-- Generated by javadoc on ... ... .. ..:..:.. UTC ....-->$|<!-- Generated by javadoc on Sun Jul 01 00:00:00 UTC 2000-->|' $f
sed -i -e 's|<META NAME="date" CONTENT="20..-..-..">|<META NAME="date" CONTENT="1970-01-01">|' $f
# Gjdoc HtmlDoclet:
sed -i -e 's%Generated by Gjdoc HtmlDoclet [0-9,.]*, part of <a href="http://www.gnu.org/software/classpath/cp-tools/" title="" target="_top">GNU Classpath Tools</a>, on .*, 20.. [0-9]*:..:.. \(a\|p\)\.m\. GMT.%Generated by Gjdoc.%' $f
sed -i -e 's%<!DOCTYPE html PUBLIC "-//gnu.org///DTD XHTML 1.1 plus Target 1.0//EN"\(.*\)GNU Classpath Tools</a>, on [A-Z][a-z]* [0-9]*, 20?? [0-9]*:??:?? \(a|p\)\.m\. GMT.</p>%<!DOCTYPE html PUBLIC "-//gnu.org///DTD XHTML 1.1 plus Target 1.0//EN"\1GNU Classpath Tools</a>, on January 1, 2009 0:00:00 a.m. GMT.</p>%' $f
sed -i -e 's%<!DOCTYPE html PUBLIC "-//gnu.org///DTD\(.*GNU Classpath Tools</a>\), on [a-zA-Z]* [0-9][0-9], 20.. [0-9]*:..:.. \(a\|p\)\.m\. GMT.</p>%<!DOCTYPE html PUBLIC "-//gnu.org///DTD\1,on May 1, 2010 1:11:42 p.m. GMT.</p>%' $f
# deprecated-list is randomly ordered, sort it for comparison
case $f in
*/deprecated-list.html)
sort $f > ${f}.sort
mv ${f}.sort $f
;;
esac
done
;;
/usr/share/javadoc/gjdoc.properties |\
/usr/share/javadoc/*/gjdoc.properties)
for f in old/$file new/$file; do
sed -i -e 's|^#[A-Z][a-z]\{2\} [A-Z][a-z]\{2\} [0-9]\{2\} ..:..:.. GMT 20..$|#Fri Jan 01 11:27:36 GMT 2009|' $f
done
;;
*/fonts.scale|*/fonts.dir|*/encodings.dir)
for f in old/$file new/$file; do
# sort files before comparing
sort $f > $f.tmp
mv $f.tmp $f
done
;;
/var/adm/perl-modules/*)
for f in old/$file new/$file; do
sed -i -e 's|^=head2 ... ... .. ..:..:.. ....: C<Module>|=head2 Wed Jul 1 00:00:00 2009: C<Module>|' $f
done
;;
/usr/share/man/man3/*3pm)
for f in old/$file new/$file; do
sed -i -e 's| 3 "20..-..-.." "perl v5....." "User Contributed Perl Documentation"$| 3 "2009-01-01" "perl v5.10.0" "User Contributed Perl Documentation"|' $f
done
;;
/usr/share/man/man*/*)
# Handles lines like:
# .TH debhelper 7 "2010-02-27" "7.4.15" "Debhelper"
# .TH DIRMNGR-CLIENT 1 2010-02-27 "Dirmngr 1.0.3" "GNU Privacy Guard"
# .TH ccmake 1 "March 06, 2010" "ccmake 2.8.1-rc3"
# .TH QEMU-IMG 1 "2010-03-14" " " " "
# .TH kdecmake 1 "May 07, 2010" "cmake 2.8.1"
# .TH "appender.h" 3 "12 May 2010" "Version 1.2.1" "log4c" \" -*- nroff -*-
# .TH"appender.h"3"TueAug312010""Version1.2.1""log4c"\"-*-nroff-*-
# .TH "OFFLINEIMAP" "1" "11 May 2010" "John Goerzen" "OfflineIMAP Manual"
# .TH gv 3guile "13 May 2010"
# .TH ARCH "1" "September 2010" "GNU coreutils 8.5" "User Commands"
#.TH "GIT\-ARCHIMPORT" "1" "09/13/2010" "Git 1\&.7\&.1" "Git Manual"
for f in old/$file new/$file; do
sed -i -e 's/.TH "\?\([^ "]*\)"\? "\?\([0-9][a-z]*\)"\? "\?\(20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]\|[A-Z][a-z]* [0-9][0-9], 20[0-9][0-9]\|[0-9]* [A-Z][a-z]* 20[0-9][0-9]\|[A-Z][a-z][a-z] [A-Z][a-z][a-z] [0-9]\+ 20[0-9][0-9]\|[A-Z][a-z]* 20[0-9][0-9]\|[0-1][0-9]/[0-9][0-9]/201[0-9]\)"\? /.TH \1 \2 "2000-01-01" /' $f
# generated by docbook xml:
#.\" Date: 09/13/2010
sed -i -e 's|Date: [0-1][0-9]/[0-9][0-9]/201[0-9]|Date: 09/13/2010|' $f
done
;;
*.elc)
# emacs lisp files
for f in old/$file new/$file; do
sed -i -e 's|Compiled by abuild@.* on ... ... .. ..:..:.. 20..$|compiled by abuild@buildhost on Wed Jul 01 00:00:00 2009|' $f
done
;;
/var/lib/texmf/web2c/*/*fmt)
# same of these are gzip compressed
for f in old/$file new/$file; do
fftype=`/usr/bin/file $f | cut -d: -f2-`
case $fftype in
*gzip\ compressed\ data*)
gunzip -cd $f > $f.tmp
mv $f.tmp $f
;;
*)
;;
esac
# date is of variable length, e.g. 2009.7.21
sed -i -e 's|(format=[a-z]*tex 20..\.[0-9]*\.[0-9]*)|(format=luatex 2009.1.1)|' $f
done
;;
*/libtool)
for f in old/$file new/$file; do
sed -i -e 's|^# Libtool was configured on host [a-z0-9]*:$|Libtool was configured on host x42:|' $f
done
;;
/etc/mail/*cf|/etc/sendmail.cf)
# from sendmail package
for f in old/$file new/$file; do
# - ##### built by abuild@build33 on Thu May 6 11:21:17 UTC 2010
sed -i -e 's|built by abuild@[a-z0-9]* on ... ... [0-9]* [0-9]*:[0-9][0-9]:[0-9][0-9] .* 20[0-9][0-9]|built by abuild@build42 on Thu May 6 11:21:17 UTC 2010|' $f
done
;;
/usr/share/doc/kde/HTML/*/*/index.cache|/usr/share/doc/kde/HTML/*/*/*/index.cache)
# various kde packages
for f in old/$file new/$file; do
sed -i -e 's%name="id[0-9]*"\([> ]\)%name="id424242"\1%g' $f
sed -i -e 's%name="[a-z]*\.id[0-9]*"%name="ftn.id111111"%g' $f
sed -i -e 's%\.html#id[0-9]*">%.html#id424242">%g' $f
sed -i -e 's%href="#\([a-z]*\.\)\?id[0-9]*">%href="#\1id0000000">%g' $f
done
;;
*/created.rid)
# ruby documentation
# file just contains a timestamp and nothing else, so ignore it
echo "Ignore $file"
return 0
;;
*/rdoc/files/*.html)
# ruby documentation
# <td>MonSep2019:02:43+00002010</td>
for f in old/$file new/$file; do
sed -i -e 's%<td>[A-Z][a-z][a-z] [A-Z][a-z][a-z] [0-9]\+ [0-9]\+:[0-9]\+:[0-9]\+ +0000 201[0-9]</td>%<td>MonSep2019:02:43+00002010</td>%g' $f
done
;;
esac
ftype=`/usr/bin/file old/$file | cut -d: -f2-`
case $ftype in
*PE32\ executable*Mono\/\.Net\ assembly*)
echo "PE32 Mono/.Net assembly: $file"
if [ -x /usr/bin/monodis ] ; then
monodis old/$file 2>/dev/null|sed -e 's/GUID = {.*}/GUID = { 42 }/;'> ${file1}
monodis new/$file 2>/dev/null|sed -e 's/GUID = {.*}/GUID = { 42 }/;'> ${file2}
if ! cmp -s ${file1} ${file2}; then
echo "$file differs ($ftype)"
diff -u ${file1} ${file2}
return 1
fi
else
echo "Cannot compare, no monodis installed"
return 1
fi
;;
*ELF*executable*|*ELF*LSB\ shared\ object*)
objdump -d --no-show-raw-insn old/$file | filter_disasm > $file1
if ! test -s $file1; then
# objdump has no idea how to handle it
if ! diff_two_files; then
ret=1
break
fi
fi
sed -i -e "s,old/,," $file1
objdump -d --no-show-raw-insn new/$file | filter_disasm > $file2
sed -i -e "s,new/,," $file2
if ! diff -u $file1 $file2 > $dfile; then
echo "$file differs in assembler output"
head -n 200 $dfile
return 1
fi
objdump -s old/$file > $file1
sed -i -e "s,old/,," $file1
objdump -s new/$file > $file2
sed -i -e "s,new/,," $file2
if ! diff -u $file1 $file2 > $dfile; then
echo "$file differs in ELF sections"
head -n 200 $dfile
else
echo "WARNING: no idea about $file"
fi
return 1
;;
*ASCII*|*text*)
if ! cmp -s old/$file new/$file; then
echo "$file differs ($ftype)"
diff -u old/$file new/$file | head -n 200
return 1
fi
;;
*directory)
# tar might package directories - ignore them here
return 0
;;
*)
if ! diff_two_files; then
return 1
fi
;;
esac
return 0
}
# We need /proc mounted for some tests, so check that it's mounted and
# complain if not.
PROC_MOUNTED=0
if [ ! -d /proc/self/ ]; then
echo "/proc is not mounted"
mount -orw -n -tproc none /proc
PROC_MOUNTED=1
fi
ret=0
for file in $files; do
if ! check_single_file $file; then
ret=1
if test -z "$check_all"; then
break
fi
fi
done
if [ "$PROC_MOUNTED" -eq "1" ]; then
echo "Unmounting proc"
umount /proc
fi
rm $file1 $file2 $dfile
rm -r $dir
exit $ret