chiark / gitweb /
dpkg (1.18.25) stretch; urgency=medium
[dpkg] / debian / dpkg.prerm
1 #!/bin/sh
2 # See deb-prerm(5).
3
4 set -e
5
6 ensure_no_triggers_noawait()
7 {
8     admindir=${DPKG_ADMINDIR:-/var/lib/dpkg}
9     pkgadmindir=$admindir/info
10
11     trig_noawait=$(find "$pkgadmindir" -name "*.triggers" -type f | \
12                    xargs -r grep -El "^(interest|activate)-(no)?await" | \
13                    sed -e 's,^.*/\([^/.:]\+\)[^/]\+$,\1,')
14
15     # Abort if we cannot possibly downgrade
16     if [ -n "$trig_noawait" ]; then
17         cat <<- MSG
18         dpkg: error: You have packages using the "interest-noawait" and/or
19         "activate-noawait" trigger directives but the dpkg version that
20         you're trying to downgrade to doesn't support them. Aborting
21         downgrade.
22
23         List of affected packages:
24
25         $trig_noawait
26         MSG
27         exit 1
28     fi
29
30     bad_triggers_files=$(find "$admindir/triggers" -type f | \
31                          xargs -r grep -l "/noawait$" || true)
32     if [ -n "$bad_triggers_files" ]; then
33         cat <<- MSG
34         dpkg: error: Some internal trigger files unexpectedly reference
35         packages tagged with "/noawait" while their corresponding
36         infodb files doesn't seem to contain any "interest-noawait"
37         directive. Aborting the downgrade as those tags are not supported
38         by the version you're trying to downgrade to.
39
40         List of internal trigger files that are affected:
41
42         $bad_triggers_files
43         MSG
44         exit 1
45     fi
46 }
47
48 downgrade_multiarch_infodb()
49 {
50     admindir=${DPKG_ADMINDIR:-/var/lib/dpkg}
51     pkgadmindir=$admindir/info
52     triggersdir=$admindir/triggers
53
54     coinst_pkgs="`ls "$pkgadmindir" | \
55         sed -n -e 's/^\([^:]\+:[^.]\+\)\..*$/\1/p' | sort -u | \
56         cut -d: -f1 | uniq -d`"
57
58     # Abort if we cannot possibly downgrade
59     if [ -n "$coinst_pkgs" ]; then
60         cat <<- MSG
61         dpkg: error: You have more than one architecture instance for some
62         installed 'Multi-Arch: same' packages, to be able to downgrade dpkg
63         you will need to have only one instance installed per package.
64
65         List of co-installed packages:
66
67         $coinst_pkgs
68         MSG
69         exit 1
70     fi
71
72     bad_dep_pkgs=$(dpkg-query -f '${Package}\t${Depends} ${Recommends} ${Suggests} ${Enhances} ${Conflicts} ${Replaces} ${Breaks}\n' -W | \
73         grep ":any" | cut -f1 | sort -u)
74     if [ -n "$bad_dep_pkgs" ]; then
75         cat <<- MSG
76         dpkg: error: Some installed packages have multiarch dependencies that
77         the old dpkg won't parse. You should get rid of them (or downgrade
78         them to versions without those dependencies) before proceeding with
79         dpkg's downgrade.
80
81         List of affected packages:
82
83         $bad_dep_pkgs
84         MSG
85         exit 1
86     fi
87
88     dep_fields='Depends|Recommends|Suggests|Enhances|Conflicts|Replaces|Breaks'
89     if grep -qE "^($dep_fields):.*:any" $admindir/available; then
90         cat <<- MSG
91         dpkg: error: Some available packages have multiarch dependencies that
92         the old dpkg won't parse. You should clear this file before proceeding
93         with dpkg's downgrade, with:
94
95           # dpkg --clear-avail
96         MSG
97         exit 1
98     fi
99
100     file_triggers_pkgs="`sed -n -e 's/^[^ ]\+ \([^:]\+\):[^.]\+$/\1/p' \
101         $triggersdir/File| sort -u`"
102
103     if [ -n "$file_triggers_pkgs" ]; then
104         cat <<-MSG
105         dpkg: error: The triggers database contains arch-qualified package
106         names that the old dpkg won't parse. You should get rid of them (or
107         downgrade them to a non Multi-Arch: same version) before proceeding
108         with dpkg's downgrade.
109
110         List of affected packages:
111
112         $file_triggers_pkgs
113         MSG
114         exit 1
115     fi
116
117     echo "Downgrading the multiarch dpkg control files database ..."
118     ls $pkgadmindir | grep : | while read oldfile; do
119         # We first do a round of hardlinks to the new names, so that the db
120         # will never be unusable for either of the dpkg versions.
121         newfile=$(echo $oldfile | sed -e 's/:[^.]\+//')
122         ln -f "$pkgadmindir/$oldfile" "$pkgadmindir/$newfile"
123     done
124 }
125
126 case "$1" in
127     upgrade)
128         # Allow the downgrade only if no package is using the
129         # (interest|activate)-noawait trigger directives
130         if dpkg --compare-versions "$2" lt 1.16.1; then
131             ensure_no_triggers_noawait
132         fi
133         # Downgrade the multiarch db to a “monoarch” db layout
134         if dpkg --compare-versions "$2" lt 1.16.2; then
135             downgrade_multiarch_infodb
136         fi
137         ;;
138
139     remove|failed-upgrade|deconfigure)
140         ;;
141
142     *)
143         echo "$0 called with unknown argument '$1'" 1>&2
144         exit 1
145         ;;
146 esac
147
148 #DEBHELPER#
149 exit 0