New, actually useful etcdiff version.
authorAntonio Ospite <ao2@openezx.org>
Sun, 1 Mar 2009 17:32:34 +0000 (18:32 +0100)
committerAntonio Ospite <ao2@openezx.org>
Sun, 1 Mar 2009 17:32:34 +0000 (18:32 +0100)
This version starts to offer some functionality useful in real world:
* use per package temp dir
* save config files and config diffs following the original path
* download packages only when needed
* diff only once per file
* show more usage examples
* update copyright info

etcdiff.sh

index b8a3be6..ea0de33 100755 (executable)
@@ -1,38 +1,74 @@
 #!/bin/sh
 #
+# Version 0.2
+#
 # etcdiff (deb-etcdiff?) shows how your current /etc dir
 # diverges from the debian distribution standard one.
 #
-# Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
+# Copyright (C) 2008,2009 Antonio Ospite <ospite@studenti.unina.it>
 # License: GPLv2 or later
 
-set -ex
 
-PROMPT_RM=-i
+# 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 -r temp     && mkdir temp
-rm $PROMPT_RM -r archives && mkdir archives
-rm $PROMPT_RM -r conf     && mkdir -p conf/patches
+rm $PROMPT_RM -rf temp     && mkdir temp
+rm $PROMPT_RM -rf archives && mkdir archives
+rm $PROMPT_RM -rf conf     && mkdir conf
 
-USERMODE="-perm /o+r"
-MAXDEPTH="-maxdepth 1"
+# Examples of file query
 
+# by list
 #FILES="/etc/sysctl.conf /etc/init.d/procps /etc/passwd-"
-FILES=$(find /etc/ $MAXDEPTH -type f $USERMODE | grep -v '.dpkg-')
+
+# 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 what installed package provides the config 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
-    cp "$file" conf/
+    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
 
@@ -41,15 +77,41 @@ do
   FILENAME=$(apt-cache show $PACKAGE | grep ^Filename | cut -d ' ' -f 2-)
   ARCHIVE=$(basename $FILENAME)
 
-  (cd archives && wget -q -nc -c $DEBIANMIRROR/$FILENAME)
-  dpkg -x archives/$ARCHIVE temp/
+  if [ ! -f archives/$ARCHIVE ];
+  then
+    ( cd archives &&
+        wget -q -nc -c $DEBIANMIRROR/$FILENAME &&
+        mkdir ../temp/$PACKAGE
+        dpkg -x $ARCHIVE ../temp/$PACKAGE
+    )
+  fi
 
-  diff -q temp/$file $file > /dev/null
-  if [ $? -eq 1 ];
+  # 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
-    diff -u temp/$file $file > conf/patches/$(basename $file).patch
-  else
     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