#!/bin/sh # # Version 0.2 # # etcdiff (deb-etcdiff?) shows how your current /etc dir # diverges from the debian distribution standard one. # # Copyright (C) 2008,2009 Antonio Ospite # License: GPLv2 or later # TODO: # Add per package etcdiff, using dpkg -L # Add per distro etcdiff using dpkg --get-selections # # Note that the first method can't consider files not in original packages, # unless some smart trick is used (new files could be in same /etc subdir of # the provided configuration files) # # The second one could even speedup the whole etcdiffing by recreating an etc # dir as per packages defaults, and do one big diff. set -x #PROMPT_RM=-i DEBIANMIRROR="http://ftp.it.debian.org/debian" rm $PROMPT_RM -rf temp && mkdir temp rm $PROMPT_RM -rf archives && mkdir archives rm $PROMPT_RM -rf conf && mkdir conf # Examples of file query # by list #FILES="/etc/sysctl.conf /etc/init.d/procps /etc/passwd-" # by command FILES=$(find /etc/apache2 -type f $USERMODE | grep -v '.dpkg-') # by command, public files, limited #USERMODE="-perm /o+r" #MAXDEPTH="-maxdepth 1" #FILES=$(find /etc/ $MAXDEPTH -type f $USERMODE | grep -v '.dpkg-') # by package name #FILES=$(dpkg -L apache2.2-common | grep '^/etc') for file in ${FILES}; do if [ ! -e $file ]; then echo "ERROR, file $file does not exist." exit 1; fi echo "-> $file" # Find out which installed package provides the config file PACKAGE=$(dpkg-query -S "$file" | cut -d ':' -f 1 | uniq 2> /dev/null) # Copy the whole file if it is not provided by default if [ "x$PACKAGE" == "x" ]; then DESTDIR=`dirname $file` # strip trailing slash [ ${DESTDIR:0:1} == '/' ] && DESTDIR=${DESTDIR:1} # RECREATE the destination dir [ -d conf/$DESTDIR ] || mkdir -p conf/$DESTDIR cp "$file" conf/$DESTDIR continue fi # Get the package from the repository and diff FILENAME=$(apt-cache show $PACKAGE | grep ^Filename | cut -d ' ' -f 2-) ARCHIVE=$(basename $FILENAME) if [ ! -f archives/$ARCHIVE ]; then ( cd archives && wget -q -nc -c $DEBIANMIRROR/$FILENAME && mkdir ../temp/$PACKAGE dpkg -x $ARCHIVE ../temp/$PACKAGE ) fi # Check for file existence before diffing, the file is not provided in # package archive, but it could have been generated by package installation # scripts if [ ! -f temp/$PACKAGE/$file ]; then echo "Warning: '$file' can't be found in package!" fi # TODO: diff only once and check filesize TMPDIFF_FILE=`mktemp /tmp/etcdiff.XXXXXXXXXX` diff -u temp/$PACKAGE/$file $file > $TMPDIFF_FILE if [ `stat -c '%s' $TMPDIFF_FILE` -eq 0 ]; then echo "$file: not changed" rm -f $TMPDIFF_FILE else DESTDIR=`dirname $file` # strip trailing slash [ ${DESTDIR:0:1} == '/' ] && DESTDIR=${DESTDIR:1} # RECREATE the destination dir [ -d conf/$DESTDIR ] || mkdir -p conf/$DESTDIR cp $TMPDIFF_FILE conf/$DESTDIR/$(basename $file).patch rm -f $TMPDIFF_FILE fi done