dpkg.prerm 4.7 KB

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