summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Makefile.am11
-rw-r--r--scripts/makepkg.sh.in170
-rw-r--r--scripts/pacman-db-upgrade.sh.in2
-rw-r--r--scripts/pacman-key.sh.in27
-rw-r--r--scripts/pacman-optimize.sh.in49
-rw-r--r--scripts/pkgdelta.sh.in2
-rw-r--r--scripts/repo-add.sh.in61
7 files changed, 175 insertions, 147 deletions
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index d89fd306..727de258 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -53,21 +53,16 @@ edit = sed \
-e 's|@BUILDSCRIPT[@]|$(BUILDSCRIPT)|g' \
-e 's|@SIZECMD[@]|$(SIZECMD)|g' \
-e 's|@SEDINPLACE[@]|$(SEDINPLACE)|g' \
- -e 's|@DUPATH[@]|$(DUPATH)|g' \
-e 's|@SCRIPTNAME[@]|$@|g' \
-e 's|@configure_input[@]|Generated from $@.sh.in; do not edit by hand.|g'
## All the scripts depend on Makefile so that they are rebuilt when the
## prefix etc. changes. Use chmod -w to prevent people from editing the
## wrong file by accident.
-# two 'test' lines- make sure we can handle both sh and py type scripts
-# third 'test' line- make sure one of the two checks succeeded
$(OURSCRIPTS): Makefile
- @echo ' ' GEN $@;
- @$(RM) $@
- @test -f $(srcdir)/$@.sh.in && m4 -P -I $(srcdir) $(srcdir)/$@.sh.in | $(edit) >$@
- @chmod +x $@
- @chmod a-w $@
+ $(AM_V_at)$(RM) $@
+ $(AM_V_GEN)test -f $(srcdir)/$@.sh.in && m4 -P -I $(srcdir) $(srcdir)/$@.sh.in | $(edit) >$@
+ $(AM_V_at)chmod +x,a-w $@
makepkg: \
$(srcdir)/makepkg.sh.in \
diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in
index 4656ab03..89cd118d 100644
--- a/scripts/makepkg.sh.in
+++ b/scripts/makepkg.sh.in
@@ -39,10 +39,10 @@ export COMMAND_MODE='legacy'
# Ensure CDPATH doesn't screw with our cd calls
unset CDPATH
-myver='@PACKAGE_VERSION@'
-confdir='@sysconfdir@'
-BUILDSCRIPT='@BUILDSCRIPT@'
-startdir="$PWD"
+declare -r myver='@PACKAGE_VERSION@'
+declare -r confdir='@sysconfdir@'
+declare -r BUILDSCRIPT='@BUILDSCRIPT@'
+declare -r startdir="$PWD"
packaging_options=('strip' 'docs' 'libtool' 'emptydirs' 'zipman' 'purge' 'upx')
other_options=('ccache' 'distcc' 'buildflags' 'makeflags')
@@ -338,10 +338,10 @@ in_array() {
return 1 # Not Found
}
-source_has_signatures(){
+source_has_signatures() {
local file
for file in "${source[@]}"; do
- if [[ $file = *.@(sig?(n)|asc) ]]; then
+ if [[ ${file%%::*} = *.@(sig?(n)|asc) ]]; then
return 0
fi
done
@@ -420,18 +420,18 @@ download_file() {
run_pacman() {
local cmd
if [[ ! $1 = -@(T|Qq) ]]; then
- printf -v cmd "%q " "$PACMAN" $PACMAN_OPTS "$@"
+ cmd=("$PACMAN" $PACMAN_OPTS "$@")
else
- printf -v cmd "%q " "$PACMAN" "$@"
+ cmd=("$PACMAN" "$@")
fi
if (( ! ASROOT )) && [[ ! $1 = -@(T|Qq) ]]; then
if type -p sudo >/dev/null; then
- cmd="sudo $cmd"
+ cmd=(sudo "${cmd[@]}")
else
- cmd="su root -c '$cmd'"
+ cmd=(su root -c "$(printf '%q ' "${cmd[@]}")")
fi
fi
- eval "$cmd"
+ "${cmd[@]}"
}
check_deps() {
@@ -677,14 +677,18 @@ check_checksums() {
fi
if (( $found )) ; then
- local expectedsum=$(tr '[:upper:]' '[:lower:]' <<< "${integrity_sums[$idx]}")
- local realsum="$(openssl dgst -${integ} "$file")"
- realsum="${realsum##* }"
- if [[ $expectedsum = $realsum ]]; then
- printf -- "$(gettext "Passed")\n" >&2
+ if [[ ${integrity_sums[$idx]} = 'SKIP' ]]; then
+ echo "$(gettext "Skipped")" >&2
else
- printf -- "$(gettext "FAILED")\n" >&2
- errors=1
+ local expectedsum=$(tr '[:upper:]' '[:lower:]' <<< "${integrity_sums[$idx]}")
+ local realsum="$(openssl dgst -${integ} "$file")"
+ realsum="${realsum##* }"
+ if [[ $expectedsum = $realsum ]]; then
+ printf -- "$(gettext "Passed")\n" >&2
+ else
+ printf -- "$(gettext "FAILED")\n" >&2
+ errors=1
+ fi
fi
fi
@@ -1087,30 +1091,62 @@ find_libdepends() {
}
find_libprovides() {
- local libprovides
- find "$pkgdir" -type f -name \*.so\* | while read filename
- do
- # check if we really have a shared object
- if LC_ALL=C readelf -h "$filename" 2>/dev/null | grep -q '.*Type:.*DYN (Shared object file).*'; then
- # 64
- soarch=$(LC_ALL=C readelf -h "$filename" | sed -n 's/.*Class.*ELF\(32\|64\)/\1/p')
- # get the string binaries link to: libfoo.so.1.2 -> libfoo.so.1
- sofile=$(LC_ALL=C readelf -d "$filename" 2>/dev/null | sed -n 's/.*Library soname: \[\(.*\)\].*/\1/p')
- [ -z "$sofile" ] && sofile="${filename##*/}"
-
- # extract the library name: libfoo.so
- soname="${sofile%%\.so\.*}.so"
- # extract the major version: 1
- soversion="${sofile##*\.so\.}"
- if in_array "${soname}" ${provides[@]}; then
- if ! in_array "${soname}=${soversion}-${soarch}" ${libprovides[@]}; then
- # libfoo.so=1-64
- echo "${soname}=${soversion}-${soarch}"
- libprovides=(${libprovides[@]} "${soname}=${soversion}-${soarch}")
+ local libprovides missing
+ for p in ${provides[@]}; do
+ missing=0
+ case "$p" in
+ *.so)
+ local filename=$(find "$pkgdir" -type f -name $p\*)
+ if [[ $filename ]]; then
+ # packages may provide multiple versions of the same library
+ for fn in ${filename[@]}; do
+ # check if we really have a shared object
+ if LC_ALL=C readelf -h "$fn" 2>/dev/null | grep -q '.*Type:.*DYN (Shared object file).*'; then
+ # get the string binaries link to (e.g. libfoo.so.1.2 -> libfoo.so.1)
+ local sofile=$(LC_ALL=C readelf -d "$fn" 2>/dev/null | sed -n 's/.*Library soname: \[\(.*\)\].*/\1/p')
+ if [[ -z "$sofile" ]]; then
+ warning "$(gettext "Library listed in %s is not versioned: %s")" "'provides'" "$p"
+ libprovides=(${libprovides[@]} "$p")
+ continue
+ fi
+
+ # get the library architecture (32 or 64 bit)
+ local soarch=$(LC_ALL=C readelf -h "$fn" | sed -n 's/.*Class.*ELF\(32\|64\)/\1/p')
+
+ # extract the library major version
+ local soversion="${sofile##*\.so\.}"
+
+ libprovides=(${libprovides[@]} "${p}=${soversion}-${soarch}")
+ else
+ warning "$(gettext "Library listed in %s is not a shared object: %s")" "'provides'" "$p"
+ libprovides=(${libprovides[@]} "$p")
+ fi
+ done
+ else
+ libprovides=(${libprovides[@]} "$p")
+ missing=1
fi
- fi
- fi
+ ;;
+ *)
+ libprovides=(${libprovides[@]} "$p")
+ ;;
+ esac
+
+ if (( missing )); then
+ warning "$(gettext "Can not find library listed in %s: %s")" "'provides'" "$p"
+ fi
done
+
+ echo ${libprovides[@]}
+}
+
+check_license() {
+ # TODO maybe remove this at some point
+ # warn if license array is not present or empty
+ if [[ -z $license ]]; then
+ warning "$(gettext "Please add a license line to your %s!")" "$BUILDSCRIPT"
+ plain "$(gettext "Example for GPL\'ed software: %s.")" "license=('GPL')"
+ fi
}
write_pkginfo() {
@@ -1120,8 +1156,7 @@ write_pkginfo() {
else
local packager="Unknown Packager"
fi
- local size="$(@DUPATH@ -sk)"
- size="$(( ${size%%[^0-9]*} * 1024 ))"
+ local size="$(find . -print0 | xargs -0 @SIZECMD@ | awk '{ sum += $1 } END { print sum }')"
msg2 "$(gettext "Generating %s file...")" ".PKGINFO"
echo "# Generated by makepkg $myver"
@@ -1144,13 +1179,15 @@ write_pkginfo() {
[[ $groups ]] && printf "group = %s\n" "${groups[@]}"
[[ $optdepends ]] && printf "optdepend = %s\n" "${optdepends[@]//+([[:space:]])/ }"
[[ $conflicts ]] && printf "conflict = %s\n" "${conflicts[@]}"
+
+ provides=($(find_libprovides))
+ [[ $provides ]] && printf "provides = %s\n" "${provides[@]}"
+
[[ $backup ]] && printf "backup = %s\n" "${backup[@]}"
- local it
- libprovides=$(find_libprovides)
+ local it
libdepends=$(find_libdepends)
- provides=("${provides[@]}" ${libprovides})
depends=("${depends[@]}" ${libdepends})
for it in "${depends[@]}"; do
@@ -1167,20 +1204,6 @@ write_pkginfo() {
fi
done
- for it in "${provides[@]}"; do
- # ignore versionless entires (those come from the PKGBUILD)
- if [[ $it = *.so ]]; then
- # check if the entry has been found by find_libprovides
- # if not, it's unneeded; tell the user so he can remove it
- if [[ ! $libprovides =~ (^|\s)${it}=.* ]]; then
- error "$(gettext "Cannot find library listed in %s: %s")" "'provides'" "$it"
- return 1
- fi
- else
- echo "provides = $it"
- fi
- done
-
for it in "${packaging_options[@]}"; do
local ret="$(check_option $it)"
if [[ $ret != "?" ]]; then
@@ -1192,12 +1215,7 @@ write_pkginfo() {
fi
done
- # TODO maybe remove this at some point
- # warn if license array is not present or empty
- if [[ -z $license ]]; then
- warning "$(gettext "Please add a license line to your %s!")" "$BUILDSCRIPT"
- plain "$(gettext "Example for GPL\'ed software: %s.")" "license=('GPL')"
- fi
+ check_license
}
check_package() {
@@ -1248,7 +1266,7 @@ create_package() {
write_pkginfo $nameofpkg > .PKGINFO
- local comp_files=".PKGINFO"
+ local comp_files=('.PKGINFO')
# check for changelog/install files
for i in 'changelog/.CHANGELOG' 'install/.INSTALL'; do
@@ -1258,7 +1276,7 @@ create_package() {
msg2 "$(gettext "Adding %s file...")" "$orig"
cp "$startdir/${!orig}" "$dest"
chmod 644 "$dest"
- comp_files+=" $dest"
+ comp_files+=("$dest")
fi
done
@@ -1280,12 +1298,12 @@ create_package() {
# bsdtar's gzip compression always saves the time stamp, making one
# archive created using the same command line distinct from another.
# Disable bsdtar compression and use gzip -n for now.
- bsdtar -cf - $comp_files * |
+ bsdtar -cf - "${comp_files[@]}" * |
case "$PKGEXT" in
- *tar.gz) gzip -c -f -n ;;
- *tar.bz2) bzip2 -c -f ;;
- *tar.xz) xz -c -z - ;;
- *tar.Z) compress -c -f ;;
+ *tar.gz) ${COMPRESSGZ[@]:-gzip -c -f -n} ;;
+ *tar.bz2) ${COMPRESSBZ2[@]:-bzip2 -c -f} ;;
+ *tar.xz) ${COMPRESSXZ[@]:-xz -c -z -} ;;
+ *tar.Z) ${COMPRESSZ[@]:-compress -c -f} ;;
*tar) cat ;;
*) warning "$(gettext "'%s' is not a valid archive extension.")" \
"$PKGEXT"; cat ;;
@@ -1345,6 +1363,8 @@ create_srcpackage() {
local srclinks="$(mktemp -d "$startdir"/srclinks.XXXXXXXXX)"
mkdir "${srclinks}"/${pkgbase}
+ check_license
+
msg2 "$(gettext "Adding %s...")" "$BUILDSCRIPT"
ln -s "${BUILDFILE}" "${srclinks}/${pkgbase}/${BUILDSCRIPT}"
@@ -1467,8 +1487,8 @@ check_sanity() {
awk -F'=' '$1 ~ /^[[:space:]]*pkgrel$/' "$BUILDFILE" | sed "s/[[:space:]]*#.*//" |
while IFS='=' read -r _ i; do
eval i=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "${i%%+([[:space:]])}")\"
- if [[ $i = *[[:space:]-]* ]]; then
- error "$(gettext "%s is not allowed to contain hyphens or whitespace.")" "pkgrel"
+ if [[ $i != +([0-9])?(.+([0-9])) ]]; then
+ error "$(gettext "%s must be a decimal.")" "pkgrel"
return 1
fi
done || ret=1
@@ -1983,6 +2003,7 @@ set -E
[[ -n ${PKGEXT} ]] && _PKGEXT=${PKGEXT}
[[ -n ${SRCEXT} ]] && _SRCEXT=${SRCEXT}
[[ -n ${GPGKEY} ]] && _GPGKEY=${GPGKEY}
+[[ -n ${PACKAGER} ]] && _PACKAGER=${PACKAGER}
# default config is makepkg.conf
MAKEPKG_CONF=${MAKEPKG_CONF:-$confdir/makepkg.conf}
@@ -2070,6 +2091,7 @@ fi
PKGEXT=${_PKGEXT:-$PKGEXT}
SRCEXT=${_SRCEXT:-$SRCEXT}
GPGKEY=${_GPGKEY:-$GPGKEY}
+PACKAGER=${_PACKAGER:-$PACKAGER}
if (( HOLDVER )) && [[ -n $FORCE_VER ]]; then
# The '\\0' is here to prevent gettext from thinking --holdver is an option
diff --git a/scripts/pacman-db-upgrade.sh.in b/scripts/pacman-db-upgrade.sh.in
index e0a049c5..894152f6 100644
--- a/scripts/pacman-db-upgrade.sh.in
+++ b/scripts/pacman-db-upgrade.sh.in
@@ -23,7 +23,7 @@
export TEXTDOMAIN='pacman-scripts'
export TEXTDOMAINDIR='@localedir@'
-myver='@PACKAGE_VERSION@'
+declare -r myver='@PACKAGE_VERSION@'
eval $(awk '/DBPath/ {print $1$2$3}' @sysconfdir@/pacman.conf)
dbroot="${DBPath:-@localstatedir@/lib/pacman/}"
diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in
index 3ea8947f..482b56d7 100644
--- a/scripts/pacman-key.sh.in
+++ b/scripts/pacman-key.sh.in
@@ -24,7 +24,7 @@
export TEXTDOMAIN='pacman-scripts'
export TEXTDOMAINDIR='@localedir@'
-myver="@PACKAGE_VERSION@"
+declare -r myver="@PACKAGE_VERSION@"
# Options
ADD=0
@@ -245,8 +245,7 @@ populate_keyring() {
fi
# Variable used for iterating on keyrings
- local key
- local key_id
+ local keys key_id
# Add keys from requested keyrings
for keyring in "${KEYRINGIDS[@]}"; do
@@ -262,14 +261,12 @@ populate_keyring() {
local -A trusted_ids
for keyring in "${KEYRINGIDS[@]}"; do
if [[ -f "${KEYRING_IMPORT_DIR}/${keyring}-trusted" ]]; then
- while read key; do
- # skip comments; these are valid in this file
- [[ $key = \#* ]] && continue
- key_id="${key%%:*}"
- if [[ -n ${key_id} ]]; then
- # Mark this key to be lsigned
- trusted_ids[$key_id]="${keyring}"
- fi
+ while IFS=: read key_id _; do
+ # skip blank lines, comments; these are valid in this file
+ [[ -z $key_id || ${key_id:0:1} = \# ]] && continue
+
+ # Mark this key to be lsigned
+ trusted_ids[$key_id]=$keyring
done < "${KEYRING_IMPORT_DIR}/${keyring}-trusted"
fi
done
@@ -294,13 +291,13 @@ populate_keyring() {
local -A revoked_ids
for keyring in "${KEYRINGIDS[@]}"; do
if [[ -f "${KEYRING_IMPORT_DIR}/${keyring}-revoked" ]]; then
- while read key; do
- key_id="$("${GPG_PACMAN[@]}" --quiet --with-colons --list-key "${key}" 2>/dev/null | grep ^pub | cut -d: -f5)"
- if [[ -n ${key_id} ]]; then
+ IFS=$'\n' read -r -d '' -a keys < "${KEYRING_IMPORT_DIR}/${keyring}-revoked"
+ while IFS=: read _ _ _ _ key_id _; do
+ if [[ -n $key_id ]]; then
# Mark this key to be disabled
revoked_ids[$key_id]="${keyring}"
fi
- done < "${KEYRING_IMPORT_DIR}/${keyring}-revoked"
+ done < <("${GPG_PACMAN[@]}" --quiet --with-colons --list-keys "${keys[@]}" 2>/dev/null)
fi
done
diff --git a/scripts/pacman-optimize.sh.in b/scripts/pacman-optimize.sh.in
index 8a4e7224..4a84c0bb 100644
--- a/scripts/pacman-optimize.sh.in
+++ b/scripts/pacman-optimize.sh.in
@@ -24,7 +24,7 @@
export TEXTDOMAIN='pacman-scripts'
export TEXTDOMAINDIR='@localedir@'
-myver='@PACKAGE_VERSION@'
+declare -r myver='@PACKAGE_VERSION@'
eval $(awk '/DBPath/ {print $1$2$3}' @sysconfdir@/pacman.conf)
dbroot="${DBPath:-@localstatedir@/lib/pacman/}"
@@ -88,9 +88,8 @@ if [[ -n $1 ]]; then
dbroot="$1"
fi
-# make sure diff is installed
-if ! type diff >/dev/null 2>&1; then
- die "$(gettext "diff tool was not found, please install diffutils.")"
+if ! type -p openssl >/dev/null; then
+ die "$(gettext "Cannot find the %s binary required for verifying integrity.")" "openssl"
fi
if [[ ! -d $dbroot || ! -d $dbroot/local ]]; then
@@ -103,8 +102,8 @@ fi
# strip any trailing slash from our dbroot
dbroot="${dbroot%/}"
-# form the path to our lockfile location
lockfile="${dbroot}/db.lck"
+localdb="${dbroot}/local"
# make sure pacman isn't running
if [[ -f $lockfile ]]; then
@@ -113,42 +112,44 @@ fi
# do not let pacman run while we do this
touch "$lockfile"
-workdir=$(mktemp -d /tmp/pacman-optimize.XXXXXXXXXX) ||
+workdir=$(mktemp -d "${TMPDIR:-/tmp}/pacman-optimize.XXXXXXXXXX") ||
die_r "$(gettext "Can not create temp directory for database building.")\n" >&2
# step 1: sum the old db
msg "$(gettext "MD5sum'ing the old database...")"
-find "$dbroot" -type f | sort | xargs md5sum > "$workdir/pacsums.old"
+(cd "$localdb" && find . -type f -print0 | \
+ xargs -0 openssl dgst -md5 | sort > "$workdir/pacsums.old")
# step 2: tar it up
-msg "$(gettext "Tar'ing up %s...")" "$dbroot"
-bsdtar -czf "$workdir/pacman-db.tar.gz" -C "$dbroot" ./
+msg "$(gettext "Tar'ing up %s...")" "$localdb"
+bsdtar -czf "$workdir/pacman-db.tar.gz" -C "$localdb" ./
if (( $? )); then
rm -rf "$workdir"
- die_r "$(gettext "Tar'ing up %s failed.")" "$dbroot"
+ die_r "$(gettext "Tar'ing up %s failed.")" "$localdb"
fi
# step 3: make and sum the new db side-by-side with the old
msg "$(gettext "Making and MD5sum'ing the new database...")"
-mkdir "$dbroot.new"
-bsdtar -xpf "$workdir/pacman-db.tar.gz" -C "$dbroot.new"
+mkdir "$localdb.new"
+bsdtar -xpf "$workdir/pacman-db.tar.gz" -C "$localdb.new"
if (( $? )); then
rm -rf "$workdir"
- die_r "$(gettext "Untar'ing %s failed.")" "$dbroot"
+ die_r "$(gettext "Untar'ing %s failed.")" "$localdb"
fi
# immediate sync following extraction should get it written continuously on HDD
msg "$(gettext "Syncing database to disk...")"
sync
-find "$dbroot.new" -type f | sort | \
- xargs md5sum | sed 's#.new##' > "$workdir/pacsums.new"
+(cd "$localdb.new" && find . -type f -print0 | \
+ xargs -0 openssl dgst -md5 | sort > "$workdir/pacsums.new")
# step 4: compare the sums
msg "$(gettext "Checking integrity...")"
-diff "$workdir/pacsums.old" "$workdir/pacsums.new" >/dev/null 2>&1
-if (( $? )); then
+read -ra old_dgst < <(openssl dgst -md5 < "$workdir/pacsums.old")
+read -ra new_dgst < <(openssl dgst -md5 < "$workdir/pacsums.new")
+if [[ ${old_dgst[@]:(-1)} != ${new_dgst[@]:(-1)} ]]; then
# failed
# leave our pacman-optimize tmpdir for checking to see what doesn't match up
- rm -rf "$dbroot.new"
+ rm -rf "$localdb.new"
die_r "$(gettext "Integrity check FAILED, reverting to old database.")"
fi
@@ -156,15 +157,15 @@ fi
msg "$(gettext "Rotating database into place...")"
fail=0
-mv "$dbroot" "$dbroot.old" || fail=1
-mv "$dbroot.new" "$dbroot" || fail=1
-chmod --reference="$dbroot.old" "$dbroot" || fail=1
-chown --reference="$dbroot.old" "$dbroot" || fail=1
+mv "$localdb" "$localdb.old" || fail=1
+mv "$localdb.new" "$localdb" || fail=1
+chmod --reference="$localdb.old" "$localdb" || fail=1
+chown --reference="$localdb.old" "$localdb" || fail=1
if (( fail )); then
# failure with our directory shuffle
- die_r "$(gettext "New database substitution failed. Check for $dbroot,\n$dbroot.old, and $dbroot.new directories.")"
+ die_r "$(gettext "New database substitution failed. Check for %s, %s, and %s directories.")" "$localdb" "$localdb.old" "$localdb.new"
fi
-rm -rf "$dbroot.old"
+rm -rf "$localdb.old"
# remove the lock file and our working directory with sums and tarfile
rm -f "$lockfile"
diff --git a/scripts/pkgdelta.sh.in b/scripts/pkgdelta.sh.in
index 35be70ce..5a2e6a37 100644
--- a/scripts/pkgdelta.sh.in
+++ b/scripts/pkgdelta.sh.in
@@ -26,7 +26,7 @@ set -o errexit
export TEXTDOMAIN='pacman-scripts'
export TEXTDOMAINDIR='@localedir@'
-myver='@PACKAGE_VERSION@'
+declare -r myver='@PACKAGE_VERSION@'
QUIET=0
diff --git a/scripts/repo-add.sh.in b/scripts/repo-add.sh.in
index 2bb9c83f..043a0b86 100644
--- a/scripts/repo-add.sh.in
+++ b/scripts/repo-add.sh.in
@@ -25,8 +25,8 @@ shopt -s extglob
export TEXTDOMAIN='pacman-scripts'
export TEXTDOMAINDIR='@localedir@'
-myver='@PACKAGE_VERSION@'
-confdir='@sysconfdir@'
+declare -r myver='@PACKAGE_VERSION@'
+declare -r confdir='@sysconfdir@'
QUIET=0
DELTA=0
@@ -203,7 +203,7 @@ create_signature() {
gpg --detach-sign --use-agent ${SIGNWITHKEY} "$dbfile" &>/dev/null || ret=$?
if (( ! ret )); then
- msg2 "$(gettext "Created signature file %s.")" "${dbfile##*/}.sig"
+ msg2 "$(gettext "Created signature file %s.")" "${dbfile##*/.tmp.}.sig"
else
warning "$(gettext "Failed to sign package database.")"
fi
@@ -424,13 +424,8 @@ elephant() {
check_repo_db() {
local repodir
- # ensure the path to the DB exists
- if [[ "$LOCKFILE" == /* ]]; then
- repodir=${LOCKFILE%/*}/
- else
- repodir=$PWD/$LOCKFILE
- repodir=${repodir%/*}/
- fi
+ # ensure the path to the DB exists; $LOCKFILE is always an absolute path
+ repodir=${LOCKFILE%/*}/
if [[ ! -d "$repodir" ]]; then
error "$(gettext "%s does not exist or is not a directory.")" "$repodir"
@@ -579,7 +574,7 @@ if [[ $cmd != "repo-add" && $cmd != "repo-remove" ]]; then
exit 1
fi
-tmpdir=$(mktemp -d /tmp/repo-tools.XXXXXXXXXX) || (\
+tmpdir=$(mktemp -d "${TMPDIR:-/tmp}/repo-tools.XXXXXXXXXX") || (\
error "$(gettext "Cannot create temp directory for database building.")"; \
exit 1)
mkdir $tmpdir/tree
@@ -637,7 +632,11 @@ if [[ -z $REPO_DB_FILE ]]; then
exit 1
fi
-LOCKFILE=$REPO_DB_FILE.lck
+if [[ $REPO_DB_FILE == /* ]]; then
+ LOCKFILE=$REPO_DB_FILE.lck
+else
+ LOCKFILE=$PWD/$REPO_DB_FILE.lck
+fi
verify_repo_extension "$REPO_DB_FILE" >/dev/null
check_repo_db
@@ -654,37 +653,51 @@ if (( success )); then
msg "$(gettext "Creating updated database file '%s'")" "$REPO_DB_FILE"
TAR_OPT=$(verify_repo_extension "$REPO_DB_FILE")
+ # $LOCKFILE is already guaranteed to be absolute so this is safe
+ dirname=${LOCKFILE%/*}
filename=${REPO_DB_FILE##*/}
+ # this ensures we create it on the same filesystem, making moves atomic
+ tempname="$dirname/.tmp.$filename"
pushd "$tmpdir/tree" >/dev/null
if ( shopt -s nullglob; files=(*); (( ${#files[*]} )) ); then
- bsdtar -c${TAR_OPT}f "$tmpdir/$filename" *
+ bsdtar -c${TAR_OPT}f "$tempname" *
else
# we have no packages remaining? zip up some emptyness
warning "$(gettext "No packages remain, creating empty database.")"
- bsdtar -c${TAR_OPT}f "$tmpdir/$filename" -T /dev/null
+ bsdtar -c${TAR_OPT}f "$tempname" -T /dev/null
fi
popd >/dev/null
- create_signature "$tmpdir/$filename"
+ create_signature "$tempname"
- [[ -f $REPO_DB_FILE ]] && mv -f "$REPO_DB_FILE" "${REPO_DB_FILE}.old"
+ # hardlink or move the previous version of the database and signature to .old
+ # extension as a backup measure
+ if [[ -f $REPO_DB_FILE ]]; then
+ ln -f "$REPO_DB_FILE" "$REPO_DB_FILE.old" 2>/dev/null || \
+ mv -f "$REPO_DB_FILE" "$REPO_DB_FILE.old"
+ fi
if [[ -f $REPO_DB_FILE.sig ]]; then
- mv -f "$REPO_DB_FILE.sig" "$REPO_DB_FILE.old.sig"
+ ln -f "$REPO_DB_FILE.sig" "$REPO_DB_FILE.old.sig" 2>/dev/null || \
+ mv -f "$REPO_DB_FILE.sig" "$REPO_DB_FILE.old.sig"
else
rm -f "$REPO_DB_FILE.old.sig"
fi
- [[ -f $tmpdir/$filename ]] && mv "$tmpdir/$filename" "$REPO_DB_FILE"
- [[ -f $tmpdir/$filename.sig ]] && mv "$tmpdir/$filename.sig" "$REPO_DB_FILE.sig"
+
+ # rotate the newly-created database and signature into place
+ mv "$tempname" "$REPO_DB_FILE"
+ if [[ -f $tempname.sig ]]; then
+ mv "$tempname.sig" "$REPO_DB_FILE.sig"
+ fi
+
dblink="${REPO_DB_FILE%.tar*}"
- target=${REPO_DB_FILE##*/}
rm -f "$dblink" "$dblink.sig"
- ln -s "$target" "$dblink" 2>/dev/null || \
- ln "$target" "$dblink" 2>/dev/null || \
+ ln -s "$filename" "$dblink" 2>/dev/null || \
+ ln "$filename" "$dblink" 2>/dev/null || \
cp "$REPO_DB_FILE" "$dblink"
if [[ -f "$REPO_DB_FILE.sig" ]]; then
- ln -s "$target.sig" "$dblink.sig" 2>/dev/null || \
- ln "$target.sig" "$dblink.sig" 2>/dev/null || \
+ ln -s "$filename.sig" "$dblink.sig" 2>/dev/null || \
+ ln "$filename.sig" "$dblink.sig" 2>/dev/null || \
cp "$REPO_DB_FILE.sig" "$dblink.sig"
fi
else