diff options
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/.gitignore | 1 | ||||
| -rw-r--r-- | scripts/Makefile.am | 5 | ||||
| -rw-r--r-- | scripts/makepkg.sh.in | 433 | ||||
| -rw-r--r-- | scripts/pacman-db-upgrade.sh.in | 121 | ||||
| -rw-r--r-- | scripts/pacman-optimize.sh.in | 8 | ||||
| -rw-r--r-- | scripts/pkgdelta.sh.in | 2 | ||||
| -rw-r--r-- | scripts/rankmirrors.sh.in | 6 | ||||
| -rw-r--r-- | scripts/repo-add.sh.in | 44 | 
8 files changed, 395 insertions, 225 deletions
| diff --git a/scripts/.gitignore b/scripts/.gitignore index eafc4930..fe4616f2 100644 --- a/scripts/.gitignore +++ b/scripts/.gitignore @@ -1,4 +1,5 @@  makepkg +pacman-db-upgrade  pacman-optimize  rankmirrors  repo-add diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 0fde3345..2962b915 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -7,6 +7,7 @@ bin_SCRIPTS = \  OURSCRIPTS = \  	makepkg \ +	pacman-db-upgrade \  	pacman-optimize \  	pkgdelta \  	rankmirrors \ @@ -14,6 +15,7 @@ OURSCRIPTS = \  EXTRA_DIST = \  	makepkg.sh.in \ +	pacman-db-upgrade.sh.in \  	pacman-optimize.sh.in \  	pkgdelta.sh.in \  	rankmirrors.sh.in \ @@ -35,10 +37,10 @@ edit = sed \  	-e 's|@sysconfdir[@]|$(sysconfdir)|g' \  	-e 's|@localstatedir[@]|$(localstatedir)|g' \  	-e 's|@prefix[@]|$(prefix)|g' \ +	-e 's|@BASH_SHELL[@]|$(BASH_SHELL)|g' \  	-e 's|@PACKAGE_VERSION[@]|$(REAL_PACKAGE_VERSION)|g' \  	-e 's|@PACKAGE_BUGREPORT[@]|$(PACKAGE_BUGREPORT)|g' \  	-e 's|@PACKAGE_NAME[@]|$(PACKAGE_NAME)|g' \ -	-e 's|@DBEXT[@]|$(DBEXT)|g' \  	-e 's|@BUILDSCRIPT[@]|$(BUILDSCRIPT)|g' \  	-e 's|@SIZECMD[@]|$(SIZECMD)|g' \  	-e 's|@SEDINPLACE[@]|$(SEDINPLACE)|g' \ @@ -61,6 +63,7 @@ $(OURSCRIPTS): Makefile  	@mv $@.tmp $@  makepkg: $(srcdir)/makepkg.sh.in +pacman-db-upgrade: $(srcdir)/pacman-db-upgrade.sh.in  pacman-optimize: $(srcdir)/pacman-optimize.sh.in  pkgdelta: $(srcdir)/pkgdelta.sh.in  rankmirrors: $(srcdir)/rankmirrors.sh.in diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in index ec664692..ac10ad3a 100644 --- a/scripts/makepkg.sh.in +++ b/scripts/makepkg.sh.in @@ -1,4 +1,4 @@ -#!/bin/bash -e +#!@BASH_SHELL@ -e  #  #   makepkg - make packages compatible for use with pacman  #   @configure_input@ @@ -27,7 +27,7 @@  # makepkg uses quite a few external programs during its execution. You  # need to have at least the following installed for makepkg to function: -#   bsdtar (libarchive), bzip2, coreutils, fakeroot, file, find (findutils), +#   awk, bsdtar (libarchive), bzip2, coreutils, fakeroot, file, find (findutils),  #   gettext, grep, gzip, openssl, sed, tput (ncurses), xz  # gettext initialization @@ -45,7 +45,7 @@ srcdir="$startdir/src"  pkgdir="$startdir/pkg"  packaging_options=('strip' 'docs' 'libtool' 'emptydirs' 'zipman' 'purge') -other_options=('ccache' 'distcc' 'makeflags' 'force') +other_options=('ccache' 'distcc' 'makeflags')  splitpkg_overrides=('pkgver' 'pkgrel' 'pkgdesc' 'arch' 'license' 'groups' \                      'depends' 'optdepends' 'provides' 'conflicts' 'replaces' \                      'backup' 'options' 'install' 'changelog') @@ -135,6 +135,8 @@ clean_up() {  	fi  	if (( ! EXIT_CODE && CLEANUP )); then +		local pkg file +  		# If it's a clean exit and -c/--clean has been passed...  		msg "$(gettext "Cleaning up...")"  		rm -rf "$pkgdir" "$srcdir" @@ -153,7 +155,7 @@ clean_up() {  			# clean up dangling symlinks to packages  			for pkg in ${pkgname[@]}; do -				for file in ${pkg}-*-*-${CARCH}${PKGEXT}; do +				for file in ${pkg}-*-*-${CARCH}{${PKGEXT},${SRCEXT}}; do  					if [[ -h $file && ! -e $file ]]; then  						rm -f $file  					fi @@ -308,7 +310,7 @@ get_downloadclient() {  	for i in "${DLAGENTS[@]}"; do  		local handler="${i%%::*}"  		if [[ $proto = $handler ]]; then -			agent="${i##*::}" +			local agent="${i##*::}"  			break  		fi  	done @@ -323,7 +325,7 @@ get_downloadclient() {  	# ensure specified program is installed  	local program="${agent%% *}"  	if [[ ! -x $program ]]; then -		local baseprog=$(basename $program) +		local baseprog="${program##*/}"  		error "$(gettext "The download program %s is not installed.")" "$baseprog"  		plain "$(gettext "Aborting...")"  		exit 1 # $E_MISSING_PROGRAM @@ -370,7 +372,7 @@ download_file() {  run_pacman() {  	local cmd  	printf -v cmd "%q " "$PACMAN" $PACMAN_OPTS "$@" -	if (( ! ASROOT )) && [[ $1 != "-T" && $1 != "-Qq" ]]; then +	if (( ! ASROOT )) && [[ ! $1 =~ ^-(T|Qq)$ ]]; then  		if [ "$(type -p sudo)" ]; then  			cmd="sudo $cmd"  		else @@ -387,6 +389,7 @@ check_deps() {  	# Also, a non-zero return value is not unexpected and we are manually dealing them  	set +E  	local ret=0 +	local pmout  	pmout=$(run_pacman -T "$@") || ret=$?  	set -E  @@ -394,7 +397,7 @@ check_deps() {  		echo "$pmout"  	elif (( ret )); then  		error "$(gettext "'%s' returned a fatal error (%i): %s")" "$PACMAN" "$ret" "$pmout" -		exit 1 +		return "$ret"  	fi  } @@ -434,17 +437,16 @@ resolve_deps() {  	local R_DEPS_SATISFIED=0  	local R_DEPS_MISSING=1 -	local deplist="$(check_deps $*)" -	if [[ -z $deplist ]]; then -		return $R_DEPS_SATISFIED -	fi +	# deplist cannot be declared like this: local deplist=$(foo) +	# Otherwise, the return value will depend on the assignment. +	local deplist +	deplist="$(set +E; check_deps $*)" || exit 1 +	[[ -z $deplist ]] && return $R_DEPS_SATISFIED  	if handle_deps $deplist; then  		# check deps again to make sure they were resolved -		deplist="$(check_deps $*)" +		deplist="$(set +E; check_deps $*)" || exit 1  		[[ -z $deplist ]] && return $R_DEPS_SATISFIED -	elif (( DEP_BIN )); then -		error "$(gettext "Failed to install all missing dependencies.")"  	fi  	msg "$(gettext "Missing Dependencies:")" @@ -543,7 +545,7 @@ generate_checksums() {  	msg "$(gettext "Generating checksums for source files...")"  	plain "" -	if [ ! $(type -p openssl) ]; then +	if ! type -p openssl >/dev/null; then  		error "$(gettext "Cannot find openssl.")"  		exit 1 # $E_MISSING_PROGRAM  	fi @@ -593,7 +595,7 @@ generate_checksums() {  check_checksums() {  	(( ! ${#source[@]} )) && return 0 -	if [ ! $(type -p openssl) ]; then +	if ! type -p openssl >/dev/null; then  		error "$(gettext "Cannot find openssl.")"  		exit 1 # $E_MISSING_PROGRAM  	fi @@ -654,7 +656,7 @@ extract_sources() {  	msg "$(gettext "Extracting Sources...")"  	local netfile  	for netfile in "${source[@]}"; do -		file=$(get_filename "$netfile") +		local file=$(get_filename "$netfile")  		if in_array "$file" ${noextract[@]}; then  			#skip source files in the noextract=() array  			#  these are marked explicitly to NOT be extracted @@ -685,9 +687,12 @@ extract_sources() {  					*) continue;;  				esac ;;  			*) -				# Don't know what to use to extract this file, -				# skip to the next file -				continue;; +				# See if bsdtar can recognize the file +				if bsdtar -tf "$file" -q '*' &>/dev/null; then +					cmd="bsdtar" +				else +					continue +				fi ;;  		esac  		local ret=0 @@ -717,6 +722,7 @@ error_function() {  	fi  	# first exit all subshells, then print the error  	if (( ! BASH_SUBSHELL )); then +		error "$(gettext "A failure occurred in %s().")" "$1"  		plain "$(gettext "Aborting...")"  		remove_deps  	fi @@ -727,7 +733,7 @@ run_function() {  	if [[ -z $1 ]]; then  		return 1  	fi -	pkgfunc="$1" +	local pkgfunc="$1"  	# clear user-specified makeflags if requested  	if [[ $(check_option makeflags) = "n" ]]; then @@ -743,8 +749,9 @@ run_function() {  	local shellopts=$(shopt -p)  	local ret=0 +	local restoretrap  	if (( LOGGING )); then -		BUILDLOG="${startdir}/${pkgbase}-${pkgver}-${pkgrel}-${CARCH}-$pkgfunc.log" +		local BUILDLOG="${startdir}/${pkgbase}-${pkgver}-${pkgrel}-${CARCH}-$pkgfunc.log"  		if [[ -f $BUILDLOG ]]; then  			local i=1  			while true; do @@ -759,12 +766,12 @@ run_function() {  		# ensure overridden package variables survive tee with split packages  		logpipe=$(mktemp -u "$startdir/logpipe.XXXXXXXX") -		mknod "$logpipe" p +		mkfifo "$logpipe"  		exec 3>&1  		tee "$BUILDLOG" < "$logpipe" &  		exec 1>"$logpipe" 2>"$logpipe"  		restoretrap=$(trap -p ERR) -		trap 'error_function' ERR +		trap 'error_function $pkgfunc' ERR  		$pkgfunc 2>&1  		eval $restoretrap  		sync @@ -772,7 +779,7 @@ run_function() {  		rm "$logpipe"  	else  		restoretrap=$(trap -p ERR) -		trap 'error_function' ERR +		trap 'error_function $pkgfunc' ERR  		$pkgfunc 2>&1  		eval $restoretrap  	fi @@ -799,6 +806,7 @@ run_build() {  }  run_package() { +	local pkgfunc  	if [[ -z $1 ]]; then  		pkgfunc="package"  	else @@ -865,13 +873,13 @@ tidy_install() {  		done  	fi -	if [[ $(check_option strip) = y && -n ${STRIP_DIRS[*]} ]]; then +	if [[ $(check_option strip) = y ]]; then  		msg2 "$(gettext "Stripping unneeded symbols from binaries and libraries...")"  		# make sure library stripping variables are defined to prevent excess stripping  		[[ -z ${STRIP_SHARED+x} ]] && STRIP_SHARED="-S"  		[[ -z ${STRIP_STATIC+x} ]] && STRIP_STATIC="-S"  		local binary -		find ${STRIP_DIRS[@]} -type f -perm -u+w 2>/dev/null | while read binary ; do +		find . -type f -perm -u+w 2>/dev/null | while read binary ; do  			case "$(file -bi "$binary")" in  				*application/x-sharedlib*)  # Libraries (.so)  					/usr/bin/strip $STRIP_SHARED "$binary";; @@ -905,56 +913,39 @@ write_pkginfo() {  	size="$(( ${size%%[^0-9]*} * 1024 ))"  	msg2 "$(gettext "Generating .PKGINFO file...")" -	echo "# Generated by makepkg $myver" >.PKGINFO +	echo "# Generated by makepkg $myver"  	if (( INFAKEROOT )); then -		echo "# using $(fakeroot -v)" >>.PKGINFO -	fi -	echo "# $(LC_ALL=C date -u)" >>.PKGINFO -	echo "pkgname = $1" >>.PKGINFO -	(( SPLITPKG )) && echo pkgbase = $pkgbase >>.PKGINFO -	echo "pkgver = $pkgver-$pkgrel" >>.PKGINFO -	echo "pkgdesc = $pkgdesc" >>.PKGINFO -	echo "url = $url" >>.PKGINFO -	echo "builddate = $builddate" >>.PKGINFO -	echo "packager = $packager" >>.PKGINFO -	echo "size = $size" >>.PKGINFO -	echo "arch = $PKGARCH" >>.PKGINFO -	if [[ $(check_option force) = "y" ]]; then -		echo "force = true" >> .PKGINFO -	fi +		echo "# using $(fakeroot -v)" +	fi +	echo "# $(LC_ALL=C date -u)" +	echo "pkgname = $1" +	(( SPLITPKG )) && echo pkgbase = $pkgbase +	echo "pkgver = $pkgver-$pkgrel" +	echo "pkgdesc = $pkgdesc" +	[[ $epoch ]] && echo "epoch = $epoch" +	echo "url = $url" +	echo "builddate = $builddate" +	echo "packager = $packager" +	echo "size = $size" +	echo "arch = $PKGARCH" + +	[[ $license ]]    && printf "license = %s\n"   "${license[@]}" +	[[ $replaces ]]   && printf "replaces = %s\n"  "${replaces[@]}" +	[[ $groups ]]     && printf "group = %s\n"     "${groups[@]}" +	[[ $depends ]]    && printf "depend = %s\n"    "${depends[@]}" +	[[ $optdepends ]] && printf "optdepend = %s\n" "${optdepends[@]}" +	[[ $conflicts ]]  && printf "conflict = %s\n"  "${conflicts[@]}" +	[[ $provides ]]   && printf "provides = %s\n"  "${provides[@]}" +	[[ $backup ]]     && printf "backup = %s\n"    "${backup[@]}"  	local it -	for it in "${license[@]}"; do -		echo "license = $it" >>.PKGINFO -	done -	for it in "${replaces[@]}"; do -		echo "replaces = $it" >>.PKGINFO -	done -	for it in "${groups[@]}"; do -		echo "group = $it" >>.PKGINFO -	done -	for it in "${depends[@]}"; do -		echo "depend = $it" >>.PKGINFO -	done -	for it in "${optdepends[@]}"; do -		echo "optdepend = $it" >>.PKGINFO -	done -	for it in "${conflicts[@]}"; do -		echo "conflict = $it" >>.PKGINFO -	done -	for it in "${provides[@]}"; do -		echo "provides = $it" >>.PKGINFO -	done -	for it in "${backup[@]}"; do -		echo "backup = $it" >>.PKGINFO -	done  	for it in "${packaging_options[@]}"; do  		local ret="$(check_option $it)"  		if [[ $ret != "?" ]]; then  			if [[ $ret = y ]]; then -				echo "makepkgopt = $it" >>.PKGINFO +				echo "makepkgopt = $it"  			else -				echo "makepkgopt = !$it" >>.PKGINFO +				echo "makepkgopt = !$it"  			fi  		fi  	done @@ -974,14 +965,18 @@ check_package() {  	local file  	for file in "${backup[@]}"; do  		if [[ ! -f $file ]]; then -			warning "$(gettext "Invalid backup entry : %s")" "$file" +			warning "$(gettext "Backup entry file not in package : %s")" "$file"  		fi  	done -	# check for references to the build directory -	if find "${pkgdir}" -type f -exec grep -q "${srcdir}" {} +; then +	# check for references to the build and package directory +	if find "${pkgdir}" -type f -exec grep -q -I "${srcdir}" {} +; then  		warning "$(gettext "Package contains reference to %s")" "\$srcdir"  	fi +	if find "${pkgdir}" -type f -exec grep -q -I "${pkgdir}" {} +; then +		warning "$(gettext "Package contains reference to %s")" "\$pkgdir" +	fi +  }  create_package() { @@ -996,6 +991,7 @@ create_package() {  	cd "$pkgdir"  	msg "$(gettext "Creating package...")" +	local nameofpkg  	if [[ -z $1 ]]; then  		nameofpkg="$pkgname"  	else @@ -1008,62 +1004,61 @@ create_package() {  		PKGARCH=$CARCH  	fi -	write_pkginfo $nameofpkg +	write_pkginfo $nameofpkg > .PKGINFO  	local comp_files=".PKGINFO" -	# check for an install script -	if [[ -n $install ]]; then -		msg2 "$(gettext "Adding install script...")" -		cp "$startdir/$install" .INSTALL -		chmod 644 .INSTALL -		comp_files="$comp_files .INSTALL" -	fi - -	# do we have a changelog? -	if [[ -n $changelog ]]; then -		msg2 "$(gettext "Adding package changelog...")" -		cp "$startdir/$changelog" .CHANGELOG -		chmod 644 .CHANGELOG -		comp_files="$comp_files .CHANGELOG" -	fi +	# check for changelog/install files +	for i in 'changelog' 'install'; do +		orig=${!i} +		dest=$(tr '[:lower:]' '[:upper:]' <<<".$i") + +		if [[ -n $orig ]]; then +			msg2 "$(gettext "Adding %s file...")" "$i" +			cp "$startdir/$orig" "$dest" +			chmod 644 "$dest" +			comp_files+=" $dest" +		fi +	done  	# tar it up  	msg2 "$(gettext "Compressing package...")" +	local EXT  	case "$PKGEXT" in  		*tar.gz)  EXT=${PKGEXT%.gz} ;;  		*tar.bz2) EXT=${PKGEXT%.bz2} ;;  		*tar.xz)  EXT=${PKGEXT%.xz} ;; +		*tar)     EXT=${PKGEXT} ;;  		*) warning "$(gettext "'%s' is not a valid archive extension.")" \  		"$PKGEXT" ; EXT=$PKGEXT ;;  	esac -	local tar_file="$PKGDEST/${nameofpkg}-${pkgver}-${pkgrel}-${PKGARCH}${EXT}" -	local pkg_file="$PKGDEST/${nameofpkg}-${pkgver}-${pkgrel}-${PKGARCH}${PKGEXT}" +	local pkg_file="$PKGDEST/${nameofpkg}-${pkgver}-${pkgrel}-${PKGARCH}${PKGEXT}"  	local ret=0  	# when fileglobbing, we want * in an empty directory to expand to  	# the null string rather than itself  	shopt -s nullglob -	bsdtar -cf - $comp_files * > "$tar_file" || ret=$? -	shopt -u nullglob +	# TODO: Maybe this can be set globally for robustness +	shopt -s -o pipefail +	bsdtar -cf - $comp_files * | +	case "$PKGEXT" in +	    *tar.gz)  gzip -c -f -n ;; +	    *tar.bz2) bzip2 -c -f ;; +	    *tar.xz)  xz -c -z - ;; +	    *tar)     cat ;; +	esac > ${pkg_file} || ret=$? -	if (( ! ret )); then -		case "$PKGEXT" in -			*tar.gz)  gzip -f -n "$tar_file" ;; -			*tar.bz2) bzip2 -f "$tar_file" ;; -			*tar.xz)  xz -z -f "$tar_file" ;; -		esac -		ret=$? -	fi +	shopt -u nullglob +	shopt -u -o pipefail  	if (( ret )); then  		error "$(gettext "Failed to create package file.")"  		exit 1 # TODO: error code  	fi -	if (( ! ret )) && [[ "$PKGDEST" != "${startdir}" ]]; then +	if (( ! ret )) && [[ ! "$PKGDEST" -ef "${startdir}" ]]; then  		ln -sf "${pkg_file}" "${pkg_file/$PKGDEST/$startdir}"  		ret=$?  	fi @@ -1129,6 +1124,7 @@ create_srcpackage() {  		*tar.gz)  TAR_OPT="z" ;;  		*tar.bz2) TAR_OPT="j" ;;  		*tar.xz)  TAR_OPT="J" ;; +		*tar)     TAR_OPT=""  ;;  		*) warning "$(gettext "'%s' is not a valid archive extension.")" \  		"$SRCEXT" ;;  	esac @@ -1142,6 +1138,16 @@ create_srcpackage() {  		error "$(gettext "Failed to create source package file.")"  		exit 1 # TODO: error code  	fi + +       if (( ! ret )) && [[ ! "$SRCPKGDEST" -ef "${startdir}" ]]; then +           ln -sf "${pkg_file}" "${pkg_file/$SRCPKGDEST/$startdir}" +           ret=$? +       fi + +       if (( ret )); then +           warning "$(gettext "Failed to create symlink to source package file.")" +       fi +  	cd "${startdir}"  	rm -rf "${srclinks}"  } @@ -1155,12 +1161,12 @@ install_package() {  		msg "$(gettext "Installing %s package group with %s -U...")" "$pkgbase" "$PACMAN"  	fi -	local pkglist +	local pkg pkglist  	for pkg in ${pkgname[@]}; do  		if [[ -f $PKGDEST/${pkg}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT} ]]; then -			pkglist="${pkglist} $PKGDEST/${pkg}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT}" +			pkglist+=" $PKGDEST/${pkg}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT}"  		else -			pkglist="${pkglist} $PKGDEST/${pkg}-${pkgver}-${pkgrel}-any${PKGEXT}" +			pkglist+=" $PKGDEST/${pkg}-${pkgver}-${pkgrel}-any${PKGEXT}"  		fi  	done @@ -1172,22 +1178,16 @@ install_package() {  check_sanity() {  	# check for no-no's in the build script -	if [[ -z $pkgname ]]; then -		error "$(gettext "%s is not allowed to be empty.")" "pkgname" -		return 1 -	fi -	if [[ -z $pkgver ]]; then -		error "$(gettext "%s is not allowed to be empty.")" "pkgver" -		return 1 -	fi -	if [[ -z $pkgrel ]]; then -		error "$(gettext "%s is not allowed to be empty.")" "pkgrel" -		return 1 -	fi +	local i +	for i in 'pkgname' 'pkgrel' 'pkgver'; do +		if [[ -z ${!i} ]]; then +			error "$(gettext "%s is not allowed to be empty.")" "$i" +			return 1 +		fi +	done -	local name -	for name in "${pkgname[@]}"; do -		if [[ ${name:0:1} = "-" ]]; then +	for i in "${pkgname[@]}"; do +		if [[ ${i:0:1} = "-" ]]; then  			error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgname"  			return 1  		fi @@ -1206,6 +1206,11 @@ check_sanity() {  		return 1  	fi +	if [[ ! $epoch =~ ^[0-9]*$ ]]; then +		error "$(gettext "%s must be an integer.")" "epoch" +		return 1 +	fi +  	if [[ $arch != 'any' ]]; then  		if ! in_array $CARCH ${arch[@]}; then  			if (( ! IGNOREARCH )); then @@ -1217,31 +1222,33 @@ check_sanity() {  		fi  	fi -	local provide -	for provide in ${provides[@]}; do -		if [[ $provide != ${provide//</} || $provide != ${provide//>/} ]]; then +	local provides_list +	eval $(awk '/^[[:space:]]*provides=/,/)/' "$BUILDFILE" | sed "s/provides=/provides_list+=/") +	for i in ${provides_list[@]}; do +		if [[ $i != ${i//</} || $i != ${i//>/} ]]; then  			error "$(gettext "Provides array cannot contain comparison (< or >) operators.")"  			return 1  		fi  	done -	local file -	for file in "${backup[@]}"; do -		if [[ ${file:0:1} = "/" ]]; then -			error "$(gettext "Invalid backup entry : %s")" "$file" +	local backup_list +	eval $(awk '/^[[:space:]]*backup=/,/)/' "$BUILDFILE" | sed "s/backup=/backup_list+=/") +	for i in "${backup_list[@]}"; do +		if [[ ${i:0:1} = "/" ]]; then +			error "$(gettext "Backup entry should not contain leading slash : %s")" "$i"  			return 1  		fi  	done -	local optdepend -	for optdepend in "${optdepends[@]}"; do -		pkg=${optdepend%%:*} -		if [[ ! $pkg =~ ^[[:alnum:]\>\<\=\.\+\_\-]*$ ]]; then -			error "$(gettext "Invalid syntax for optdepend : '%s'")" "$optdepend" +	local optdepends_list +	eval $(awk '/^[[:space:]]*optdepends=/,/)/' "$BUILDFILE" | sed "s/optdepends=/optdepends_list+=/") +	for i in "${optdepends_list[@]}"; do +		local pkg=${i%%:*} +		if [[ ! $pkg =~ ^[[:alnum:]\>\<\=\.\+\_\-]+$ ]]; then +			error "$(gettext "Invalid syntax for optdepend : '%s'")" "$i"  		fi  	done -	local i  	for i in 'changelog' 'install'; do  		local filelist=$(sed -n "s/^[[:space:]]*$i=//p" "$BUILDFILE")   		local file @@ -1256,17 +1263,18 @@ check_sanity() {  	done  	local valid_options=1 -	local opt known kopt -	for opt in ${options[@]}; do +	local known kopt options_list +	eval $(awk '/^[[:space:]]*options=/,/)/' "$BUILDFILE" | sed "s/options=/options_list+=/") +	for i in ${options_list[@]}; do  		known=0  		# check if option matches a known option or its inverse  		for kopt in ${packaging_options[@]} ${other_options[@]}; do -			if [[ ${opt} = ${kopt} || ${opt} = "!${kopt}" ]]; then +			if [[ ${i} = ${kopt} || ${i} = "!${kopt}" ]]; then  				known=1  			fi  		done  		if (( ! known )); then -			error "$(gettext "options array contains unknown option '%s'")" "$opt" +			error "$(gettext "options array contains unknown option '%s'")" "$i"  			valid_options=0  		fi  	done @@ -1275,22 +1283,20 @@ check_sanity() {  	fi  	if (( ${#pkgname[@]} > 1 )); then -		for pkg in ${pkgname[@]}; do -			if [ "$(type -t package_${pkg})" != "function" ]; then -				error "$(gettext "missing package function for split package '%s'")" "$pkg" +		for i in ${pkgname[@]}; do +			if ! declare -f package_${i} >/dev/null; then +				error "$(gettext "missing package function for split package '%s'")" "$i"  				return 1  			fi  		done  	fi -	if [[ -n "${PKGLIST[@]}" ]]; then -		for pkg in ${PKGLIST[@]}; do -			if ! in_array $pkg ${pkgname[@]}; then -				error "$(gettext "requested package %s is not provided in %s")" "$pkg" "$BUILDFILE" -				return 1 -			fi -		done -	fi +	for i in ${PKGLIST[@]}; do +		if ! in_array $i ${pkgname[@]}; then +			error "$(gettext "requested package %s is not provided in %s")" "$i" "$BUILDFILE" +			return 1 +		fi +	done  	return 0  } @@ -1313,27 +1319,27 @@ devel_check() {  		# Also do a brief check to make sure we have the VCS tool available.  		oldpkgver=$pkgver  		if [[ -n ${_darcstrunk} && -n ${_darcsmod} ]] ; then -			[ $(type -p darcs) ] || return 0 +			type -p darcs >/dev/null || return 0  			msg "$(gettext "Determining latest darcs revision...")"  			newpkgver=$(date +%Y%m%d)  		elif [[ -n ${_cvsroot} && -n ${_cvsmod} ]] ; then -			[ $(type -p cvs) ] || return 0 +			type -p cvs >/dev/null || return 0  			msg "$(gettext "Determining latest cvs revision...")"  			newpkgver=$(date +%Y%m%d)  		elif [[ -n ${_gitroot} && -n ${_gitname} ]] ; then -			[ $(type -p git) ] || return 0 +			type -p git >/dev/null || return 0  			msg "$(gettext "Determining latest git revision...")"  			newpkgver=$(date +%Y%m%d)  		elif [[ -n ${_svntrunk} && -n ${_svnmod} ]] ; then -			[ $(type -p svn) ] || return 0 +			type -p svn >/dev/null || return 0  			msg "$(gettext "Determining latest svn revision...")"  			newpkgver=$(LC_ALL=C svn info $_svntrunk | sed -n 's/^Last Changed Rev: \([0-9]*\)$/\1/p')  		elif [[ -n ${_bzrtrunk} && -n ${_bzrmod} ]] ; then -			[ $(type -p bzr) ] || return 0 +			type -p bzr >/dev/null || return 0  			msg "$(gettext "Determining latest bzr revision...")"  			newpkgver=$(bzr revno ${_bzrtrunk})  		elif [[ -n ${_hgroot} && -n ${_hgrepo} ]] ; then -			[ $(type -p hg) ] || return 0 +			type -p hg >/dev/null || return 0  			msg "$(gettext "Determining latest hg revision...")"  			if [[ -d ./src/$_hgrepo ]] ; then  				cd ./src/$_hgrepo @@ -1380,15 +1386,17 @@ devel_update() {  }  backup_package_variables() { +	local var  	for var in ${splitpkg_overrides[@]}; do -		indirect="${var}_backup" +		local indirect="${var}_backup"  		eval "${indirect}=(\"\${$var[@]}\")"  	done  }  restore_package_variables() { +	local var  	for var in ${splitpkg_overrides[@]}; do -		indirect="${var}_backup" +		local indirect="${var}_backup"  		if [[ -n ${!indirect} ]]; then  			eval "${var}=(\"\${$indirect[@]}\")"  		else @@ -1397,12 +1405,41 @@ restore_package_variables() {  	done  } +run_split_packaging() { +	for pkg in ${pkgname[@]}; do +		pkgdir="$pkgdir/$pkg" +		mkdir -p "$pkgdir" +		chmod a-s "$pkgdir" +		backup_package_variables +		run_package $pkg +		tidy_install +		create_package $pkg +		restore_package_variables +		pkgdir="${pkgdir%/*}" +	done +} + +# Canonicalize a directory path if it exists +canonicalize_path() { +	local path="$1"; + +	if [[ -d $path ]]; then +		( +			cd "$path" +			pwd -P +		) +	else +		echo "$path" +	fi +} +  # getopt like parser  parse_options() {  	local short_options=$1; shift;  	local long_options=$1; shift;  	local ret=0;  	local unused_options="" +	local i  	while [[ -n $1 ]]; do  		if [[ ${1:0:2} = '--' ]]; then @@ -1438,7 +1475,7 @@ parse_options() {  		elif [[ ${1:0:1} = '-' ]]; then  			for ((i=1; i<${#1}; i++)); do  				if [[ $short_options =~ ${1:i:1} ]]; then -					if [[ $short_options =~ "${1:i:1}:" ]]; then +					if [[ $short_options =~ ${1:i:1}: ]]; then  						if [[ -n ${1:$i+1} ]]; then  							printf ' -%s' "${1:i:1}"  							printf " '%s'" "${1:$i+1}" @@ -1535,7 +1572,7 @@ There is NO WARRANTY, to the extent permitted by law.\n")"  # PROGRAM START  # determine whether we have gettext; make it a no-op if we do not -if [ ! $(type -t gettext) ]; then +if ! type -p gettext >/dev/null; then  	gettext() {  		echo "$@"  	} @@ -1546,11 +1583,11 @@ ARGLIST=("$@")  # Parse Command Line Options.  OPT_SHORT="AcCdefFghiLmop:rRsV"  OPT_LONG="allsource,asroot,ignorearch,clean,cleancache,nodeps" -OPT_LONG="$OPT_LONG,noextract,force,forcever:,geninteg,help,holdver" -OPT_LONG="$OPT_LONG,install,log,nocolor,nobuild,pkg:,rmdeps,repackage,skipinteg" -OPT_LONG="$OPT_LONG,source,syncdeps,version,config:" +OPT_LONG+=",noextract,force,forcever:,geninteg,help,holdver" +OPT_LONG+=",install,log,nocolor,nobuild,pkg:,rmdeps,repackage,skipinteg" +OPT_LONG+=",source,syncdeps,version,config:"  # Pacman Options -OPT_LONG="$OPT_LONG,noconfirm,noprogressbar" +OPT_LONG+=",noconfirm,noprogressbar"  OPT_TEMP="$(parse_options $OPT_SHORT $OPT_LONG "$@" || echo 'PARSE_OPTIONS FAILED')"  if [[ $OPT_TEMP = *'PARSE_OPTIONS FAILED'* ]]; then  	# This is a small hack to stop the script bailing with 'set -e' @@ -1562,8 +1599,8 @@ unset OPT_SHORT OPT_LONG OPT_TEMP  while true; do  	case "$1" in  		# Pacman Options -		--noconfirm)      PACMAN_OPTS="$PACMAN_OPTS --noconfirm" ;; -		--noprogressbar)  PACMAN_OPTS="$PACMAN_OPTS --noprogressbar" ;; +		--noconfirm)      PACMAN_OPTS+=" --noconfirm" ;; +		--noprogressbar)  PACMAN_OPTS+=" --noprogressbar" ;;  		# Makepkg Options  		--allsource)      SOURCEONLY=2 ;; @@ -1601,10 +1638,10 @@ while true; do  	shift  done -#preserve environment variables -_PKGDEST=${PKGDEST} -_SRCDEST=${SRCDEST} -_SRCPKGDEST=${SRCPKGDEST} +# preserve environment variables and canonicalize path +[[ -n ${PKGDEST} ]] && _PKGDEST=$(canonicalize_path ${PKGDEST}) +[[ -n ${SRCDEST} ]] && _SRCDEST=$(canonicalize_path ${SRCDEST}) +[[ -n ${SRCPKGDEST} ]] && _SRCPKGDEST=$(canonicalize_path ${SRCPKGDEST})  # default config is makepkg.conf  MAKEPKG_CONF=${MAKEPKG_CONF:-$confdir/makepkg.conf} @@ -1638,12 +1675,12 @@ if [[ -t 2 && ! $USE_COLOR = "n" && $(check_buildenv color) = "y" ]]; then  		RED="${BOLD}$(tput setaf 1)"  		YELLOW="${BOLD}$(tput setaf 3)"  	else -		ALL_OFF="\033[1;0m" -		BOLD="\033[1;1m" -		BLUE="${BOLD}\033[1;34m" -		GREEN="${BOLD}\033[1;32m" -		RED="${BOLD}\033[1;31m" -		YELLOW="${BOLD}\033[1;33m" +		ALL_OFF="\e[1;0m" +		BOLD="\e[1;1m" +		BLUE="${BOLD}\e[1;34m" +		GREEN="${BOLD}\e[1;32m" +		RED="${BOLD}\e[1;31m" +		YELLOW="${BOLD}\e[1;33m"  	fi  fi  readonly ALL_OFF BOLD BLUE GREEN RED YELLOW @@ -1677,7 +1714,7 @@ fi  if (( CLEANCACHE )); then  	#fix flyspray feature request #5223 -	if [[ -n $SRCDEST && $SRCDEST != $startdir ]]; then +	if [[ -n $SRCDEST && ! $SRCDEST -ef "${startdir}" ]]; then  		msg "$(gettext "Cleaning up ALL files from %s.")" "$SRCDEST"  		echo -n "$(gettext "    Are you sure you wish to do this? ")"  		echo -n "$(gettext "[y/N]")" @@ -1719,7 +1756,7 @@ if (( ! INFAKEROOT )); then  		plain "$(gettext "Please rerun makepkg without the --asroot flag.")"  		exit 1 # $E_USER_ABORT  	elif [[ $(check_buildenv fakeroot) = "y" ]] && (( EUID > 0 )); then -		if [ ! $(type -p fakeroot) ]; then +		if ! type -p fakeroot >/dev/null; then  			error "$(gettext "Fakeroot must be installed if using the 'fakeroot' option")"  			plain "$(gettext "in the BUILDENV array in %s.")" "$MAKEPKG_CONF"  			exit 1 @@ -1739,7 +1776,7 @@ fi  # check for sudo if we will need it during makepkg execution  if (( ! ( ASROOT || INFAKEROOT ) && ( DEP_BIN || RMDEPS || INSTALL ) )); then -	if [ ! "$(type -p sudo)" ]; then +	if ! type -p sudo >/dev/null; then  		warning "$(gettext "Sudo can not be found. Will use su to acquire root privileges.")"  	fi  fi @@ -1795,14 +1832,12 @@ if (( ${#pkgname[@]} > 1 )); then  fi  # test for available PKGBUILD functions -# The exclamation mark is required here to avoid triggering the ERR trap when -# a tested function does not exist. -if [[ $(! type -t build) = "function" ]]; then +if declare -f build >/dev/null; then  	BUILDFUNC=1  fi -if [ "$(type -t package)" = "function" ]; then +if declare -f package >/dev/null; then  	PKGFUNC=1 -elif [ $SPLITPKG -eq 0 -a "$(type -t package_${pkgname})" = "function" ]; then +elif [[ $SPLITPKG -eq 0 ]] && declare -f package_${pkgname} >/dev/null; then  	SPLITPKG=1  fi @@ -1875,17 +1910,7 @@ if (( INFAKEROOT )); then  		fi  		create_package  	else -		for pkg in ${pkgname[@]}; do -			pkgdir="$pkgdir/$pkg" -			mkdir -p "$pkgdir" -			chmod a-s "$pkgdir" -			backup_package_variables -			run_package $pkg -			tidy_install -			create_package $pkg -			restore_package_variables -			pkgdir="${pkgdir%/*}" -		done +		run_split_packaging  	fi  	msg "$(gettext "Leaving fakeroot environment.")" @@ -1911,20 +1936,20 @@ if (( NODEPS || ( (NOBUILD || REPKG) && !DEP_BIN ) )); then  	if (( NODEPS || ( REPKG && PKGFUNC ) )); then  		warning "$(gettext "Skipping dependency checks.")"  	fi -elif [ $(type -p "${PACMAN%% *}") ]; then +elif type -p "${PACMAN%% *}" >/dev/null; then  	if (( RMDEPS )); then -		original_pkglist=($(run_pacman -Qq | sort))    # required by remove_dep +		original_pkglist=($(run_pacman -Qq))    # required by remove_dep  	fi  	deperr=0 -	msg "$(gettext "Checking Runtime Dependencies...")" +	msg "$(gettext "Checking runtime dependencies...")"  	resolve_deps ${depends[@]} || deperr=1 -	msg "$(gettext "Checking Buildtime Dependencies...")" +	msg "$(gettext "Checking buildtime dependencies...")"  	resolve_deps ${makedepends[@]} || deperr=1  	if (( RMDEPS )); then -		current_pkglist=($(run_pacman -Qq | sort))    # required by remove_deps +		current_pkglist=($(run_pacman -Qq))    # required by remove_deps  	fi  	if (( deperr )); then @@ -2003,17 +2028,7 @@ else  			fi  			create_package  		else -			for pkg in ${pkgname[@]}; do -				pkgdir="$pkgdir/$pkg" -				mkdir -p "$pkgdir" -				chmod a-s "$pkgdir" -				backup_package_variables -				run_package $pkg -				tidy_install -				create_package $pkg -				restore_package_variables -				pkgdir="${pkgdir%/*}" -			done +			run_split_packaging  		fi  	else  		if (( ! REPKG && ( PKGFUNC || SPLITPKG ) )); then diff --git a/scripts/pacman-db-upgrade.sh.in b/scripts/pacman-db-upgrade.sh.in new file mode 100644 index 00000000..4e6194fa --- /dev/null +++ b/scripts/pacman-db-upgrade.sh.in @@ -0,0 +1,121 @@ +#!@BASH_SHELL@ -e +# +#   pacman-db-upgrade - upgrade the local pacman db to a newer format +#   @configure_input@ +# +#   Copyright (c) 2010 Pacman Development Team <pacman-dev@archlinux.org> +# +#   This program is free software; you can redistribute it and/or modify +#   it under the terms of the GNU General Public License as published by +#   the Free Software Foundation; either version 2 of the License, or +#   (at your option) any later version. +# +#   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, see <http://www.gnu.org/licenses/>. +# + +# gettext initialization +export TEXTDOMAIN='pacman' +export TEXTDOMAINDIR='@localedir@' + +myver='@PACKAGE_VERSION@' + +eval $(awk '/DBPath/ {print $1$2$3}' @sysconfdir@/pacman.conf) +dbroot="${DBPath:-@localstatedir@/lib/pacman/}" + +msg() { +	local mesg=$1; shift +	printf "==> ${mesg}\n" "$@" >&2 +} + +error () { +	local mesg=$1; shift +	printf "==> ERROR: ${mesg}\n" "$@" >&2 +} +usage() { +	printf "pacman-db-upgrade (pacman) %s\n\n" "$myver" +	printf "$(gettext "Usage: %s [pacman_db_root]")\n\n" "$0" +} + +version() { +	printf "pacman-db-upgrade (pacman) %s\n" "$myver" +	printf "$(gettext "\ +Copyright (c) 2010 Pacman Development Team <pacman-dev@archlinux.org>.\n\ +This is free software; see the source for copying conditions.\n\ +There is NO WARRANTY, to the extent permitted by law.\n")" +} + +die() { +	error "$@" +	exit 1 +} + +die_r() { +	rm -f "$lockfile" +	die "$@" +} + +# PROGRAM START + +# determine whether we have gettext; make it a no-op if we do not +if ! type gettext &>/dev/null; then +	gettext() { +		echo "$@" +	} +fi + +if [[ $1 = "-h" || $1 = "--help" ]]; then +	usage +	exit 0 +fi + +if [[ $1 = "-V" || $1 = "--version" ]]; then +	version +	exit 0 +fi + +if [[ -n $1 ]]; then +	dbroot="$1" +fi + +if [[ ! -d $dbroot || ! -d $dbroot/local ]]; then +	die "$(gettext "%s does not exist or is not a directory.")" "$dbroot" +fi + +if [[ ! -w $dbroot ]]; then +	die "$(gettext "You must have correct permissions to upgrade the database.")" +fi + +# strip any trailing slash from our dbroot +dbroot="${dbroot%/}" +# form the path to our lockfile location +lockfile="${dbroot}/db.lck" + +# make sure pacman isn't running +if [[ -f $lockfile ]]; then +	die "$(gettext "Pacman lock file was found. Cannot run while pacman is running.")" +fi +# do not let pacman run while we do this +touch "$lockfile" + +# pacman-3.4 to 3.5 upgrade - merge depends into desc +if [[ $(find "$dbroot"/local -name depends) ]]; then +	msg "$(gettext "Pre-3.5 database format detected - upgrading...")" +	for i in "$dbroot"/local/*; do +		if [[ -f "$i"/depends ]]; then +			cat "$i"/depends >> "$i"/desc +			rm "$i"/depends +		fi +	done +	msg "$(gettext "Done.")" +fi + +# remove the lock file +rm -f "$lockfile" + +# vim: set ts=2 sw=2 noet: diff --git a/scripts/pacman-optimize.sh.in b/scripts/pacman-optimize.sh.in index 78b2345b..2404291e 100644 --- a/scripts/pacman-optimize.sh.in +++ b/scripts/pacman-optimize.sh.in @@ -1,4 +1,4 @@ -#!/bin/bash +#!@BASH_SHELL@  #  #   pacman-optimize  #   @configure_input@ @@ -25,7 +25,9 @@ export TEXTDOMAIN='pacman'  export TEXTDOMAINDIR='@localedir@'  myver='@PACKAGE_VERSION@' -dbroot='@localstatedir@/lib/pacman/' + +eval $(awk '/DBPath/ {print $1$2$3}' @sysconfdir@/pacman.conf) +dbroot="${DBPath:-@localstatedir@/lib/pacman/}"  msg() {  	local mesg=$1; shift @@ -99,7 +101,7 @@ if ! type diff >/dev/null 2>&1; then  	die "$(gettext "diff tool was not found, please install diffutils.")"  fi -if [[ ! -d $dbroot ]]; then +if [[ ! -d $dbroot || ! -d $dbroot/local ]]; then  	die "$(gettext "%s does not exist or is not a directory.")" "$dbroot"  fi diff --git a/scripts/pkgdelta.sh.in b/scripts/pkgdelta.sh.in index 1550fa10..6bc3f5da 100644 --- a/scripts/pkgdelta.sh.in +++ b/scripts/pkgdelta.sh.in @@ -1,4 +1,4 @@ -#!/bin/bash +#!@BASH_SHELL@  #  #   pkgdelta - create delta files for use with pacman and repo-add  #   @configure_input@ diff --git a/scripts/rankmirrors.sh.in b/scripts/rankmirrors.sh.in index b0dc1ab7..64d5a73c 100644 --- a/scripts/rankmirrors.sh.in +++ b/scripts/rankmirrors.sh.in @@ -1,4 +1,4 @@ -#!/bin/bash +#!@BASH_SHELL@  #  #   rankmirrors - read a list of mirrors from a file and rank them by speed  #   @configure_input@ @@ -25,7 +25,7 @@ usage() {  	echo "Usage: rankmirrors [options] MIRRORFILE | URL"  	echo  	echo "Ranks pacman mirrors by their connection and opening speed. Pacman mirror" -	echo "files are located in /etc/pacman.d/. It can also rank one mirror if the URL is" +	echo "files are located in @sysconfdir@/pacman.d/. It can also rank one mirror if the URL is"  	echo "provided."  	echo  	echo "Options:" @@ -85,7 +85,7 @@ getfetchurl() {  	if [[ -z $reponame || $reponame = $replacedurl ]]; then  		echo "fail"  	else -		local fetchurl="${replacedurl}/$reponame@DBEXT@" +		local fetchurl="${replacedurl}/$reponame.db"  		echo "$fetchurl"  	fi  } diff --git a/scripts/repo-add.sh.in b/scripts/repo-add.sh.in index 283ad07a..d09d1b48 100644 --- a/scripts/repo-add.sh.in +++ b/scripts/repo-add.sh.in @@ -1,4 +1,4 @@ -#!/bin/bash +#!@BASH_SHELL@  #  #   repo-add - add a package to a given repo database file  #   repo-remove - remove a package entry from a given repo database file @@ -28,6 +28,7 @@ myver='@PACKAGE_VERSION@'  confdir='@sysconfdir@'  QUIET=0 +DELTA=0  REPO_DB_FILE=  LOCKFILE=  CLEAN_LOCK=0 @@ -37,6 +38,7 @@ startdir="$PWD"  umask 0022  msg() { +	(( QUIET )) && return  	local mesg=$1; shift  	printf "==> ${mesg}\n" "$@" >&1  } @@ -60,7 +62,7 @@ error() {  # print usage instructions  usage() {  	printf "repo-add, repo-remove (pacman) %s\n\n" "$myver" -	printf "$(gettext "Usage: repo-add [-q] <path-to-db> <package|delta> ...\n")" +	printf "$(gettext "Usage: repo-add [-d] [-q] <path-to-db> <package|delta> ...\n")"  	printf "$(gettext "Usage: repo-remove [-q] <path-to-db> <packagename|delta> ...\n\n")"  	printf "$(gettext "\  repo-add will update a package database by reading a package file.\n\ @@ -72,6 +74,10 @@ packages to remove can be specified on the command line.\n\n")"  	printf "$(gettext "\  Use the -q/--quiet flag to minimize output to basic messages, warnings,\n\  and errors\n\n")" +	printf "$(gettext "\ +Use the -d/--delta flag to automatically generate and add a delta file\n\ +between the old entry and the new one, if the old package file is found\n\ +next to the new one.\n\n")"  	echo "$(gettext "Example:  repo-add /path/to/repo.db.tar.gz pacman-3.0.0.pkg.tar.gz")"  	echo "$(gettext "Example:  repo-remove /path/to/repo.db.tar.gz kernel26")"  } @@ -127,13 +133,12 @@ db_write_delta()  	pkgentry=$(find_pkgentry $pkgname)  	if [[ -z $pkgentry ]]; then +		error "$(gettext "No database entry for package '%s'.")" "$pkgname"  		return 1  	fi  	deltas="$pkgentry/deltas" -	# create deltas file if it does not already exist  	if [[ ! -f $deltas ]]; then -		msg2 "$(gettext "Creating 'deltas' db entry...")" -		echo -e "%DELTAS%" >>$deltas +		echo -e "%DELTAS%" >$deltas  	fi  	# get md5sum and compressed size of package  	md5sum="$(openssl dgst -md5 "$deltafile")" @@ -144,10 +149,9 @@ db_write_delta()  	newfile=$(xdelta3 printhdr $deltafile | grep "XDELTA filename (output)" | sed 's/.*: *//')  	if grep -q "$oldfile.*$newfile" $deltas; then -		warning "$(gettext "An entry for '%s' already existed")" "$deltafile"  		sed -i.backup "/$oldfile.*$newfile/d" $deltas && rm -f $deltas.backup -		msg2 "$(gettext "Removing existing entry '%s'...")" "$deltafile"  	fi +	msg2 "$(gettext "Adding 'deltas' entry : %s -> %s")" "$oldfile" "$newfile"  	echo ${deltafile##*/} $md5sum $csize $oldfile $newfile >> $deltas  	return 0 @@ -184,7 +188,7 @@ db_write_entry()  {  	# blank out all variables  	local pkgfile="$1" -	local pkgname pkgver pkgdesc csize size md5sum url arch builddate packager force \ +	local pkgname pkgver pkgdesc epoch csize size md5sum url arch builddate packager force \  		_groups _licenses _replaces _depends _conflicts _provides _optdepends  	local OLDIFS="$IFS" @@ -228,6 +232,14 @@ db_write_entry()  	if [[ -d $pkgname-$pkgver ]]; then  		warning "$(gettext "An entry for '%s' already existed")" "$pkgname-$pkgver" +	else +		if [ $DELTA -eq 1 ]; then +			pkgentry=$(find_pkgentry $pkgname) +			if [ -n "$pkgentry" ]; then +				local oldfilename=$(grep -A1 FILENAME $pkgentry/desc | tail -n1) +				local oldfile="$(dirname $1)/$oldfilename" +			fi +		fi  	fi  	# remove an existing entry if it exists, ignore failures @@ -261,6 +273,11 @@ db_write_entry()  	[[ -n $builddate ]] && echo -e "%BUILDDATE%\n$builddate\n" >>desc  	[[ -n $packager ]] && echo -e "%PACKAGER%\n$packager\n" >>desc  	write_list_entry "REPLACES" "$_replaces" "desc" +	# remain backward-compatible for now; put a force entry in the database +	if [[ -n $epoch ]]; then +		echo -e "%EPOCH%\n#epoch\n" >>desc +		echo -e "%FORCE%\n" >>desc +	fi  	[[ -n $force ]] && echo -e "%FORCE%\n" >>desc  	# create depends entry @@ -274,6 +291,16 @@ db_write_entry()  	cd "$startdir" +	# create a delta file +	if [ -n "$oldfilename" -a -f "$oldfile" ]; then +		delta=$(pkgdelta -q $oldfile $1) +		if [ -f "$delta" ]; then +			db_write_delta $delta +		else +			warning "$(gettext "Old package file not found : %s")" "$oldfilename" +		fi +	fi +  	return 0  } # end db_write_entry @@ -446,6 +473,7 @@ success=0  for arg in "$@"; do  	case "$arg" in  		-q|--quiet) QUIET=1;; +		-d|--delta) DELTA=1;;  		*)  			if [[ -z $REPO_DB_FILE ]]; then  				REPO_DB_FILE="$arg" | 
