diff options
author | Xavier Chantry <shiningxc@gmail.com> | 2009-03-03 17:05:14 +0100 |
---|---|---|
committer | Xavier Chantry <shiningxc@gmail.com> | 2009-03-15 18:10:24 +0100 |
commit | 59b4725bbb881140fea47dd2d1b09cef37e8a9dc (patch) | |
tree | edc24ee4f1a5555b765b9f2430d89b557a3eb60c /scripts | |
parent | a556bc57fccf9b35f9b2eca08ddae595c3a75592 (diff) |
repo-add : new locking system
Weird things could happen if several repo-add were run concurrently on the
same database. The introduced locking system will prevent this to happen.
Signed-off-by: Xavier Chantry <shiningxc@gmail.com>
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/repo-add.sh.in | 58 |
1 files changed, 45 insertions, 13 deletions
diff --git a/scripts/repo-add.sh.in b/scripts/repo-add.sh.in index 5643bda3..a760d1b1 100644 --- a/scripts/repo-add.sh.in +++ b/scripts/repo-add.sh.in @@ -28,7 +28,10 @@ myver='@PACKAGE_VERSION@' confdir='@sysconfdir@' QUIET=0 -REPO_DB_FILE="" +REPO_DB_FILE= +LOCKFILE= +CLEAN_LOCK=0 +startdir="$PWD" # ensure we have a sane umask set umask 0022 @@ -219,7 +222,7 @@ db_write_entry() return 1 fi - pushd "$gstmpdir" 2>&1 >/dev/null + cd "$gstmpdir" if [ -d "$pkgname-$pkgver" ]; then warning "$(gettext "An entry for '%s' already existed")" "$pkgname-$pkgver" @@ -264,7 +267,7 @@ db_write_entry() write_list_entry "PROVIDES" "$_provides" "depends" write_list_entry "OPTDEPENDS" "$_optdepends" "depends" - popd 2>&1 >/dev/null + cd "$startdir" # preserve the modification time # Xav : what for? @@ -295,6 +298,15 @@ db_remove_entry() { check_repo_db() { + # check lock file + if ( set -o noclobber; echo "$$" > "$LOCKFILE") 2> /dev/null; then + CLEAN_LOCK=1 + else + error "$(gettext "Failed to acquire lockfile: %s.")" "$LOCKFILE" + [ -f "$LOCKFILE" ] && error "$(gettext "Held by %s")" "$(cat $LOCKFILE)" + exit 1 + fi + if [ -f "$REPO_DB_FILE" ]; then if ! (bsdtar -tf "$REPO_DB_FILE" | grep -q "/desc"); then error "$(gettext "Repository file '%s' is not a proper pacman database.")" "$REPO_DB_FILE" @@ -367,6 +379,23 @@ remove() fi } +trap_exit() +{ + echo + error "$@" + exit 1 +} + +clean_up() { + local exit_code=$? + + cd "$startdir" + [ -d "$gstmpdir" ] && rm -rf "$gstmpdir" + [ $CLEAN_LOCK -eq 1 -a -f "$LOCKFILE" ] && rm -f "$LOCKFILE" + + exit $exit_code +} + # PROGRAM START # determine whether we have gettext; make it a no-op if we do not @@ -387,11 +416,6 @@ if [ $# -lt 2 ]; then exit 1 fi -# main routine -gstmpdir=$(mktemp -d /tmp/repo-tools.XXXXXXXXXX) || (\ - error "$(gettext "Cannot create temp directory for database building.")"; \ - exit 1) - # figure out what program we are cmd="$(basename $0)" if [ "$cmd" != "repo-add" -a "$cmd" != "repo-remove" ]; then @@ -399,6 +423,15 @@ if [ "$cmd" != "repo-add" -a "$cmd" != "repo-remove" ]; then exit 1 fi +gstmpdir=$(mktemp -d /tmp/repo-tools.XXXXXXXXXX) || (\ + error "$(gettext "Cannot create temp directory for database building.")"; \ + exit 1) + +trap 'clean_up' EXIT +trap 'trap_exit "$(gettext "TERM signal caught. Exiting...")"' TERM HUP QUIT +trap 'trap_exit "$(gettext "Aborted by user! Exiting...")"' INT +trap 'trap_exit "$(gettext "An unknown error has occured. Exiting...")"' ERR + success=0 # parse arguments for arg in "$@"; do @@ -413,6 +446,7 @@ for arg in "$@"; do *) if [ -z "$REPO_DB_FILE" ]; then REPO_DB_FILE="$arg" + LOCKFILE="$REPO_DB_FILE.lck" check_repo_db else case "$cmd" in @@ -437,14 +471,14 @@ if [ $success -eq 1 ]; then filename=$(basename "$REPO_DB_FILE") - pushd "$gstmpdir" 2>&1 >/dev/null + cd "$gstmpdir" if [ -n "$(ls)" ]; then bsdtar -c${TAR_OPT}f "$filename" * else # the database will be moved to .old below, and there will be no new one to replace it error "$(gettext "All packages have been removed from the database. Deleting '%s'.")" "$REPO_DB_FILE" fi - popd 2>&1 >/dev/null + cd "$startdir" [ -f "$REPO_DB_FILE" ] && mv -f "$REPO_DB_FILE" "${REPO_DB_FILE}.old" [ -f "$gstmpdir/$filename" ] && mv "$gstmpdir/$filename" "$REPO_DB_FILE" @@ -452,7 +486,5 @@ else msg "$(gettext "No packages modified, nothing to do.")" fi -# remove the temp directory used to unzip -[ -d "$gstmpdir" ] && rm -rf "$gstmpdir" - +exit 0 # vim: set ts=2 sw=2 noet: |