#!/bin/bash # -*- coding: utf-8 -*- # msidiff - compare two MSI files table content with diff # (originally based on rpmdev-diff) # # Copyright (c) 2004-2010 Ville Skyttä # Copyright (c) 2013 Red Hat, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA set -e unset CDPATH tmpdir= diffopts= list= long= tables= diffcopts=-Nup diffoopts=-U0 trap cleanup EXIT cleanup() { set +e [ -z "$tmpdir" -o ! -d "$tmpdir" ] || rm -rf "$tmpdir" } version() { cat <." } usage() { cat <&2 || echo "Error: file does not exist: '$file'" >&2 exit 1 fi done tmpdir=`mktemp -d ${TMPDIR:-/tmp}/msidiff.XXXXXX` mkdir "$tmpdir/old" "$tmpdir/new" msidump --signature --tables --directory "$tmpdir/old" $1 >/dev/null msidump --signature --tables --directory "$tmpdir/new" $2 >/dev/null if ${list:-false} || ${long:-false} ; then msiextract --directory "$tmpdir/old/files" $1 >/dev/null msiextract --directory "$tmpdir/new/files" $2 >/dev/null fi cd "$tmpdir" # Did the archives uncompress into base dirs? if [[ $(ls -1d old/* | wc -l) -eq 1 ]] ; then old=$(ls -1d old/*) else old=old fi if [[ $(ls -1d new/* | wc -l) -eq 1 ]] ; then new=$(ls -1d new/*) else new=new fi # Fixup base dirs to the same level. if [[ $(basename "$old") != $(basename "$new") ]] ; then if [[ $old != old ]] ; then mv "$old" . old=`basename "$old"` fi if [[ $new != new ]] ; then mv "$new" . new=`basename "$new"` fi fi # Tables mode is the default. if [[ -z $list$tables$long ]] ; then tables=true else tables=${tables:-false} fi list=${list:-false} long=${long:-false} # Here we go. if $tables ; then set +e diff -r ${diffopts:-$diffcopts} "$old" "$new" [[ $? -eq 0 || $? -eq 1 ]] || exit $? set -e fi if $list ; then find "$old/files" | sort | cut -d/ -f 3- -s > "$old.files" find "$new/files" | sort | cut -d/ -f 3- -s > "$new.files" set +e diff ${diffopts:-$diffoopts} "$old.files" "$new.files" [[ $? -eq 0 || $? -eq 1 ]] || exit $? set -e fi if $long ; then find "$old/files" -ls | \ perl -pe "s|^(?:[\d\s]*)(\S+)(?:\s+\d+)(.+)$|\1\2| ; s|.*\s\Q$old/files\E$|| ; s|(\s)\Q$old/files/\E|\1|" | \ sort > "$old.files" find "$new/files" -ls | \ perl -pe "s|^(?:[\d\s]*)(\S+)(?:\s+\d+)(.+)$|\1\2| ; s|.*\s\Q$new/files\E$|| ; s|(\s)\Q$new/files/\E|\1|" | \ sort > "$new.files" set +e diff ${diffopts:-$diffoopts} "$old.files" "$new.files" [[ $? -eq 0 || $? -eq 1 ]] || exit $? set -e fi