summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Gregory <andrew.gregory.8@gmail.com>2014-08-20 22:46:08 +0200
committerAllan McRae <allan@archlinux.org>2014-09-23 13:25:44 +0200
commit793b9c3b42c1af9b18a3cc8d08dd058f9cb96d93 (patch)
treebd73dae2fa0744a9cdcc69ef7816efbe55c31900
parente4773b1b82a737a74434d778c1043367a480205a (diff)
downloadpacman-793b9c3b42c1af9b18a3cc8d08dd058f9cb96d93.tar.gz
pacman-793b9c3b42c1af9b18a3cc8d08dd058f9cb96d93.tar.xz
Extend database upgrade script to handle alpm db version 9
Original-work-by: Allan McRae <allan@archlinux.org> Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com> Signed-off-by: Allan McRae <allan@archlinux.org>
-rw-r--r--scripts/pacman-db-upgrade.sh.in96
1 files changed, 86 insertions, 10 deletions
diff --git a/scripts/pacman-db-upgrade.sh.in b/scripts/pacman-db-upgrade.sh.in
index 70562e09..d2d317bf 100644
--- a/scripts/pacman-db-upgrade.sh.in
+++ b/scripts/pacman-db-upgrade.sh.in
@@ -76,6 +76,12 @@ get_opt_from_config() {
done <"$conffile"
}
+resolve_dir() {
+ local d="$(cd "$1"; pwd -P)"
+ [[ $d == */ ]] || d+=/
+ printf "%s" "$d"
+}
+
# PROGRAM START
# determine whether we have gettext; make it a no-op if we do not
@@ -143,18 +149,88 @@ 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.")"
+if [[ -f "${dbroot}"/local/ALPM_DB_VERSION ]]; then
+ db_version=$(cat "${dbroot}"/local/ALPM_DB_VERSION)
fi
+if [[ -z "$db_version" ]]; then
+ # 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
+
+ # pacman 4.1 to 4.2 upgrade - remove directory symlink support
+ dirlist=()
+
+ unset GREP_OPTIONS
+ while IFS= read -r dir; do
+ dirlist+=("${pacroot}${dir%/}")
+ done < <(grep -h '/$' "$dbroot"/local/*/files | sort -ru)
+
+ mapfile -t dirlist < <(find "${dirlist[@]}" -maxdepth 0 -type l)
+
+ if [[ ${#dirlist[@]} != 0 ]]; then
+ msg "$(gettext "Pre-4.2 database format detected - upgrading...")"
+
+ pacroot="$(resolve_dir "$pacroot")"
+
+ for dir in "${dirlist[@]}"; do
+ realdir="$(resolve_dir "$dir")"
+
+ # verify realdir is inside root
+ if [[ ${realdir:0:${#pacroot}} != $pacroot ]]; then
+ warning "$(gettext "symlink '%s' points outside pacman root, manual repair required")" "$dir"
+ continue
+ fi
+
+ # convert to an appropriate form for the replacement
+ olddir="${dir:${#pacroot}}/"
+ newdir="${realdir:${#pacroot}}"
+
+ # construct the parents of the new directory
+ parents=""
+ parent="$(dirname "$newdir")"
+ while [[ $parent != "." ]]; do
+ parents+="$parent/\n"
+ parent="$(dirname "$parent")"
+ done
+
+ for f in "$dbroot"/local/*/files; do
+ awk -v "olddir=$olddir" -v "newdir=$newdir" -v "parents=$parents" '
+ BEGIN {
+ i = length(olddir) + 1
+ file = substr(newdir, 0, length(newdir) - 1)
+ }
+ {
+ if ($0 == olddir) {
+ # replace symlink with its target, including parents
+ printf("%s", parents)
+ printf("%s\n", newdir)
+ } else if ($0 == file) {
+ # newdir already existed as a file, skip it
+ } else if (index($0, olddir) == 1) {
+ # update paths that were under olddir
+ printf("%s%s\n", newdir, substr($0, i))
+ } else {
+ # print everything else as-is
+ print
+ }
+ }' "$f" | grep . | LC_ALL=C sort -u > "$f.tmp"
+ mv "$f.tmp" "$f"
+ done
+ done
+ fi
+fi
+
+echo "9" > "$dbroot"/local/ALPM_DB_VERSION
+
# remove the lock file
rm -f "$lockfile"