#! /bin/bash -e # Copyright 2007 by Alexander Schmehl # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 (only) of the GNU General Public License # 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 # # # Implemented with ideas and suggestions by: # # Michael Koch (one should use traps to clean up) # Thomas Viehmann (wrote a very elegant python version) # Alexander Wirt (wrote a fastand memory consuming) version in perl) # Kevin Mark (for the hint, that one cause of slowness might be zgrep) # version () { echo -e "This is conflicts 20070310-1, a script to find conflicts of a Debian package. This code is copyright 2007 by Alexander Schmehl The software may be freely redistributed under the terms and conditions of the GNU General Public Licence, version 2." } usage () { echo -e "This script tries to detect conflicts of a given Debian package file with other packages in the archive.\n\nNothing special needs to be installed, just the usual stuff like sed, grep and awk.\nThe first Parameter must be the full path to the debian package file, you would like to check.\nOptionally you can specify a full path to a Contents-.gz file to be used to check against.\nIf you don't specify a path to a Contents-.gz file, the script will try to download one\nfrom ftp.debian.org. You'll need to have wget installed for this feature to work.\n\nChecking might take some time (up to several minutes in worst case), so please be patient.\nOh, and I should note, that you'll need some disk space in your /tmp directory. Depending on\nthe uncompressed size of the Contents-.gz you are using, it might be up to 350MB. Sorry,\nI don't found a way to save diskspace without wasting a lot of internal memory." warning; } warning () { echo -e "\n\nWARNING!\n========\n\nDue to the fact, that Debian packages might create files during installation,\nbut don't need to document those files anywere, this script is unable to detect\n_all_ possible conflicts.\n\nSo don't use it as excuse, if you forgot to add a conflect, this script didn't detect ;)" } cleanup () { rm -f "$TMPFILE" "$UNPACKCONTENTS" "$FILES" "$SORTED" } trap 'cleanup' EXIT ## we need at least one Paramteter, which should be a file if [[ -z "$1" || "$1" == "-h" || "$1" == "--help" ]]; then usage exit 0 elif [[ "$1" == "--version" || "$1" == "-v" ]]; then version exit 0 elif [[ ! -f "$1" ]]; then usage exit 1 fi; DEBFILE=$1; echo "Packagefile: $DEBFILE" ## First try to get the package name PACKAGE="$(dpkg -I $DEBFILE |grep Package|cut -d" " -f3)" echo "Packagename: $PACKAGE" ## If we got a second Paramter, it's the path to the contents file if [ -n "$2" ]; then ## if the file doesn't exists, we ignore it if [ -f "$2" ]; then CONTENTS="$2"; fi ## oh... no contents-file via parameter... let's guess where it might be ## First let's see if we apt-file has something? elif [ -f "$(ls /var/cache/apt/apt-file/*_debian_dists_sid_Contents*.gz 2>/dev/null|head -n1)" ]; then CONTENTS="$(ls /var/cache/apt/apt-file/*_debian_dists_sid_Contents*.gz|head -n1)" ## maybe we have a local mirror available? elif [ -f "$(ls /pub/debian/dists/sid/Contents-*.gz 2>/dev/null|head -n1)" ]; then CONTENTS="$(ls /pub/debian/dists/sid/Contents-*.gz|head -n1)" ## Still nothing? Okay, let's try to download it. elif [ -x "$(which wget)" ]; then echo -e "Found no suitable Contents-File. Trying to download one. Please be patient...\n" ## Yeah, the TMPFILE thing is a bit ugly; but if we download it we should later clean it, ## so it's easier to clean TMPFILE, than to reguess if we should clean $CONTENTS TMPFILE="$(mktemp)" ARCH="$(dpkg-architecture -qDEB_BUILD_ARCH)" wget -O"$TMPFILE" http://ftp.debian.org/dists/sid/Contents-"$ARCH".gz CONTENTS="$TMPFILE" fi echo "Using Contents-File: $CONTENTS" #unpacking the contents file for faster access and delete the first 32 lines UNPACKCONTENTS=$(mktemp) zcat $CONTENTS|sed -n '33~1p' > $UNPACKCONTENTS ## dpkg -c "$1": list files in the .deb package ## egrep -v "/$": omit directories ## awk '{print $6}': only the filename, not the modes, size, dates ## sed -e "s-$\./--" delete the "./" at the start of each line, since they are so in the Contents ## sort exactly that :) ## Note: Since LC_COLLATE affects sorts behaviour, we override it FILES=$(mktemp) LC_COLLATE=POSIX dpkg -c $DEBFILE |egrep -v "/$"|awk '{print $6}'|sed -e "s-^\./--"|sort > $FILES SORTED=$(mktemp) LC_COLLATE=POSIX sort -m -o "$SORTED" "$UNPACKCONTENTS" "$FILES" echo -e "\n\nList of possible conflicting files and packages:" ## egrep will exit 1 if it doesn't find any line, so we'll need to handle that awk -F"\t" 'prev == $1 {print} {prev=$1}' "$SORTED"|egrep -v "/$PACKAGE$"||true X=$? case "$X" in 0) warning ;; 1) echo "Found no conflicting files." warning ;; 2) echo "egrep exited with an error while searching for double lines in $SORTED." ;; esac