[pacman-dev] [PATCH v2 6/9] pacdiff: improve speed, accuracy finding active configs using pacmandb

Jonathan Frazier eyeswide at gmail.com
Mon Jul 22 21:22:57 EDT 2013


This is a new search type, using -p or --pacmandb options. It reads
config file locations directly from the local pacman db. It will find
active configs anywhere they are defined in installed packages. It is
not dependant on outside configs such as updatedb.conf or scanning a
large set of directories for find.

This will find more pacnews than find when searching with the current
default of /etc, and it is faster than both find and updatedb when
searching the entire fs. When run directly after an update, the local db
is more likely to be cached than all files in /etc or / as other methods
read. This will increase performance further post upgrade.

After a package is removed and a pacsave is created, this method will
not find these pacsaves until the base config is added to the local db
again. These files have no influence in a working system and only take
up a few blocks of disk space.

Active configs need to be dealt with immediately to keep a system
working. pacsaves related to removed configs can remain for weeks or
months without problems. I would recommend occasionally running other
methods such as --locate to remove them.

Signed-off-by: Jonathan Frazier <eyeswide at gmail.com>
---
 contrib/pacdiff.sh.in | 52 +++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 46 insertions(+), 6 deletions(-)

diff --git a/contrib/pacdiff.sh.in b/contrib/pacdiff.sh.in
index f106c17..8f1a0e7 100644
--- a/contrib/pacdiff.sh.in
+++ b/contrib/pacdiff.sh.in
@@ -18,6 +18,8 @@
 #   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 
+shopt -s extglob
+
 declare -r myname='pacdiff'
 declare -r myver='@PACKAGE_VERSION@'
 
@@ -25,7 +27,7 @@ diffprog=${DIFFPROG:-vimdiff}
 diffsearchpath=${DIFFSEARCHPATH:-/etc}
 USE_COLOR='y'
 declare -a oldsaves
-declare -i FIND=0 LOCATE=0
+declare -i FIND=0 LOCATE=0 PACDB=0
 
 m4_include(../scripts/library/output_format.sh)
 
@@ -33,11 +35,12 @@ usage() {
 	cat <<EOF
 $myname is a simple pacnew/pacorig/pacsave updater.
 
-Usage: $myname [-l | -f] [--nocolor]
+Usage: $myname [-l | -f | -p] [--nocolor]
 
 Search Options:     select one, default: find
   -l/--locate       scan using locate
   -f/--find         scan using find
+  -p/--pacmandb     scan active config files from pacman db
 
 General Options:
   --nocolor         remove colors from output
@@ -58,11 +61,32 @@ version() {
 	echo 'Copyright (C) 2013 Pacman Development Team <pacman-dev at archlinux.org>'
 }
 
+print_existing() {
+	[[ -f "$1" ]] && printf '%s\0' "$1"
+}
+
+print_existing_pacsave(){
+	for f in "${1}"?(.+([0-9])); do
+		[[ -f $f ]] && printf '%s\0' "$f"
+	done
+}	
+
 cmd() {
 	if (( LOCATE )); then
 		locate -0 -e -b \*.pacnew \*.pacorig \*.pacsave '*.pacsave.[0-9]*'
 	elif (( FIND )); then
 		find $diffsearchpath \( -name \*.pacnew -o -name \*.pacorig -o -name \*.pacsave -o -name '*.pacsave.[0-9]*' \) -print0
+	elif (( PACDB )); then
+		awk '/^%BACKUP%$/ {
+		while (getline) {
+			if (/^$/) { nextfile }
+				print $1
+			}
+		}' "${pac_db}"/*/files | while read -r bkup; do
+			print_existing "/$bkup.pacnew"
+			print_existing "/$bkup.pacorig"
+			print_existing_pacsave "/$bkup.pacsave"
+		done
 	fi
 }
 
@@ -72,8 +96,10 @@ while [[ -n "$1" ]]; do
 			LOCATE=1;;
 		-f|--find)
 			FIND=1;;
+		-p|--pacmandb)
+			PACDB=1;;
 		--nocolor)
-			USE_COLOR='n' ;;
+			USE_COLOR='n';;
 		-V|--version)
 			version; exit 0;;
 		-h|--help)
@@ -86,12 +112,26 @@ done
 
 m4_include(../scripts/library/term_colors.sh)
 
-case $(( FIND+LOCATE )) in
+case $(( FIND+LOCATE+PACDB )) in
 	0) FIND=1;; # set the default search option
 	[^1]) error "Only one search option may be used at a time"
 	 	usage; exit 1;;
 esac
 
+if (( PACDB )); then
+	if [[ ! -r @sysconfdir@/pacman.conf ]]; then
+		error "unable to read @sysconfdir@/pacman.conf"
+		usage; exit 1
+	fi
+
+	eval $(awk '/DBPath/ {print $1$2$3}' @sysconfdir@/pacman.conf)
+	pac_db="${DBPath:- at localstatedir@/lib/pacman/}local"
+	if [[ ! -d "${pac_db}" ]]; then
+		error "unable to read pacman db %s". "${pac_db}"
+		usage; exit 1
+	fi
+fi
+
 # see http://mywiki.wooledge.org/BashFAQ/020
 while IFS= read -u 3 -r -d '' pacfile; do
 	file="${pacfile%.pac*}"
@@ -120,8 +160,8 @@ while IFS= read -u 3 -r -d '' pacfile; do
 				r|R) rm -v "$pacfile"; break ;;
 				o|O) mv -v "$pacfile" "$file"; break ;;
 				v|V)
-				$diffprog "$pacfile" "$file"
-				rm -iv "$pacfile"; break ;;
+					$diffprog "$pacfile" "$file"
+					rm -iv "$pacfile"; break ;;
 				s|S) break ;;
 				*) ask "Invalid answer. Try again: [v/s/r/o] "; continue ;;
 			esac
-- 
1.8.3.2



More information about the pacman-dev mailing list