Skip to content

Instantly share code, notes, and snippets.

@schtobia
Last active November 29, 2019 10:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save schtobia/8f2d851c0353350e2c89b4ed2c11e75a to your computer and use it in GitHub Desktop.
Save schtobia/8f2d851c0353350e2c89b4ed2c11e75a to your computer and use it in GitHub Desktop.
#!/bin/bash
# Usage: debdiffconf.sh <filename>
# Produce on stdout, a diff of <filename> against the first installed Debian
# package found that provides it.
# Returns the exit code of diff if everything worked, 3 or 4 otherwise.
base_name=$(basename $0)
required=( apt-get apt-file diff dpkg-deb dpkg-query realpath)
for binary in "${required[@]}"
do
[ -x "$(command -v "$binary")" ] ||
{
echo -e "Error: Necessary program \'$binary\' is not installed. Aborting now.\n" >&2
exit 4
}
done
if [ $# -eq 0 ]
then
echo "No arguments supplied, please pass in a filename. Try something like:\n\n$base_name /etc/squid/squid.conf\n" >&2
exit 4
else
FILE=$(readlink -f "$1")
fi
while read -r PACKAGE
do
# verify from first installed package
if dpkg-query --showformat='${Status}\n' -W "$PACKAGE" > /dev/null
then
# create a unique tmpdir that is still recognizable in the system
DIR=$(mktemp --tmpdir -d "$base_name-$PACKAGE.XXXXXXXXXX")
if cd "$DIR"
then
# install cleanup trap
trap "{ cd -; rm -rf "$DIR"; exit $?; }" EXIT INT TERM HUP PIPE
else
echo -e "Cannot chdir to \'$DIR\'. Aborting now." >&2
exit 1
fi
echo "Trying $PACKAGE…" >&2
apt-get download "$PACKAGE" >&2
# downloaded archive is the only file present...
ARCHIVE=$(ls)
mkdir contents
# extract entire archive
dpkg-deb -x "$ARCHIVE" contents/ >&2
[ -f "contents$FILE" ] && diff --unified --minimal "contents$FILE" "$FILE"
exit 0
fi
done < <(apt-file -l search "$FILE")
# if we are here, it means we have found no suitable package
echo "Could not find original package for $FILE" >&2
exit 3
@desrod
Copy link

desrod commented Nov 22, 2019

Here's a cleaned-up/updated version of the above:

#!/bin/bash

# Usage: debdiffconf.sh <filename>
# Produce on stdout, a diff of <filename> against the first installed Debian
# package found that provides it.
# Returns the exit code of diff if everything worked, 3 or 4 otherwise.

required=( apt-get apt-file diff dpkg-deb dpkg-query realpath)
for binary in "${required[@]}"; do
        if ! [ -x "$(command -v "$binary")" ]; then
                printf "Error: Necessary program \'%s\' is not installed Aborting now.\n\n" "$binary" >&2
                exit 4
        fi
done

if [ $# -eq 0 ]; then
    printf "No arguments supplied, please pass in a filename. Try something like:\n\n"
    printf "%s /etc/squid/squid.conf\n" "$0"
    exit 4
else
    FILE=$(readlink -f "$1")
fi

while read -r PACKAGE
do
  # verify from first installed package
  if dpkg-query -W --showformat='${Status}\n' | grep installed > /dev/null
  then
    DIR=$(mktemp -d)
    cd "$DIR" || exit
    echo "Trying $PACKAGE..." >&2
    apt-get download "$PACKAGE" >&2
    # downloaded archive is the only file present...
    ARCHIVE=$(ls)
    mkdir contents
    # extract entire archive
    dpkg-deb -x "$ARCHIVE" contents/ >&2
    if [ -f "contents$FILE" ]
    then
      # package contained required file
      diff --minimal "contents$FILE" "$FILE"
      RET=$?
      # cleanup
      cd || exit
      rm -Rf "$DIR"
      # exit entire script as this is the main shell
      # with the return code from diff
      exit $RET
    else
      # cleanup
      cd || exit
      rm -Rf "$DIR"
    fi
  fi
done < <(apt-file -l search "$FILE")
# if we are here, it means we have found no suitable package
echo "Could not find original package for $FILE" >&2
exit 3

@schtobia
Copy link
Author

Thanks, included in 0334afa .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment