dpkg.prerm 4.7 KB

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