--- /dev/null
+`deb-download-from-pool.sh` is a script to download a group of related deb
+packages built from the same "src" package directly from the "pool" directory
+of a Debian mirror.
+
+It could be used to downgrade a group of packages when the latest version
+introduces a regression, and previous versions are not available anymore for
+the current distribution.
+
+
+Examples
+========
+
+Get version from testing
+------------------------
+
+Sometimes a package gets updated in Debian unstable but it introduces
+regressions, so reverting to the version in testing can be useful::
+
+ $ lsb_release --description
+ Description: Debian GNU/Linux unstable (sid)
+ $ rmadison -a $(dpkg-architecture -qDEB_BUILD_ARCH) libllvm7
+ libllvm7 | 1:7-6 | testing | amd64
+ libllvm7 | 1:7.0.1~+rc2-2 | unstable | amd64
+
+However just specifying the version to `apt-get` is not enough if the old
+version is not available anymore for unstable::
+
+ $ sudo apt-get install libllvm7=1:7-6
+ Reading package lists... Done
+ Building dependency tree
+ Reading state information... Done
+ E: Version '1:7-6' for 'libllvm7' was not found
+
+The official mechanism to get packages from different suites is to use pinning_.
+
+.. _pinning: https://wiki.debian.org/AptPreferences#Pinning-1
+
+Without pinning_ getting packages from different suites does not work::
+
+ $ sudo apt-get install -t testing libllvm7=1:7-6
+ Reading package lists... Done
+ E: The value 'testing' is invalid for APT::Default-Release as such a release is not available in the sources
+
+With `deb-download-from-pool.sh` it is possible to get packages from *testing*
+even if they are not directly available from *unstable* anymore::
+
+ $ ./deb-download-from-pool.sh libllvm7 7-6
+
+
+Get ancient version from snapshot.debian.org
+--------------------------------------------
+
+Debian provides snapshots of mirrors at http://snapshot.debian.org/ and using
+these it is possible to download ancient package versions.
+
+Specifying a snapshot mirrors makes it possible to download very old packages::
+
+ MIRROR=http://snapshot.debian.org/archive/debian/20180904T211902Z/ \
+ DEBUG_MIRROR=http://snapshot.debian.org/archive/debian-debug/20180904T210823Z/ \
+ ./deb-download-from-pool.sh dash 0.5.8-2.10
+
+
+Known Bugs
+==========
+
+If no version is passed the script will list available versions on the mirror,
+but it will do so regardless of what binaries are actually available for the
+current architecture of the host running the script.
+
+So it may list versions which could not be downloaded for the host.
+
+A more reliable way to list version could be something like the following::
+
+ rmadison -a $(dpkg-architecture -qDEB_BUILD_ARCH) package_name
+
+However this would not work with arbitrary mirrors, or snapshots.
--- /dev/null
+#!/bin/sh
+#
+# deb-download-from-pool.sh - download specific packages from the pool
+#
+# Copyright (C) 2018 Antonio Ospite <ao2@ao2.it>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+set -e
+
+MIRROR="${MIRROR:-https://deb.debian.org/debian}"
+DEBUG_MIRROR="${DEBUG_MIRROR:-http://debug.mirrors.debian.org/debian-debug}"
+
+usage() {
+ PROG_NAME=$(basename "$0")
+ cat <<EOF
+usage: $PROG_NAME [--all|-h|--help] <package> [<version>]
+
+Helper script to download specific packages from the pool directory of
+a Debian mirror.
+
+
+Options:
+ --all download all related packages even if currently
+ uninstalled
+ -h, --help display this usage message and exit
+
+
+Notes:
+
+Some settings can be changed via environment variables:
+ SOURCE_PACKAGE
+ POOL_DIRECTORY
+ MIRROR
+ DEBUG_MIRROR
+EOF
+}
+
+download() {
+ dpkg --validate-pkgname -- "$1" || { usage 1>&2; exit 1; }
+
+ PACKAGE="$1"
+
+ if [ "x$SOURCE_PACKAGE" = "x" ];
+ then
+ SOURCE_PACKAGE=$(apt-cache show "$PACKAGE" | grep Source | head -1 | cut -d ' ' -f 2)
+ if [ "x$SOURCE_PACKAGE" = "x" ];
+ then
+ SOURCE_PACKAGE="$PACKAGE"
+ fi
+ fi
+
+ if [ "x$POOL_DIRECTORY" = "x" ];
+ then
+ POOL_DIRECTORY=$(apt-cache showsrc "$SOURCE_PACKAGE" | grep Directory | head -1 | cut -d ' ' -f 2)
+ fi
+
+ POOL_URL="${MIRROR}/${POOL_DIRECTORY}"
+
+ if [ "x$2" = "x" ];
+ then
+ echo "Available versions, pass one of these as the second argument:"
+ wget -q "$POOL_URL" -O - | grep "${SOURCE_PACKAGE}_.*\\.dsc" | sed -e 's/^.*<a .*>.*_\(.*\)\.dsc<\/a>.*$/\1/g'
+ exit $?
+ fi
+
+ dpkg --validate-version -- "$2" || { usage 1>&2; exit 1; }
+
+ VERSION="$2"
+
+ ARCH=$(dpkg-architecture -qDEB_BUILD_ARCH)
+ PACKAGES=$(wget -q "$POOL_URL" -O - | \
+ grep -e "${VERSION}[^_]*_${ARCH}" \
+ -e "${VERSION}[^_]*_all" | \
+ sed -e 's/^.* href="\([^"]*\)".*$/\1/g')
+
+ for p in $PACKAGES;
+ do
+ PNAME=$(echo "$p" | cut -d '_' -f 1);
+ STATUS=$(grep-status -X \( -F Architecture "$ARCH" --or -F Architecture all \) --and -X -F Package "$PNAME" -n -s Status || true)
+ if [ "$STATUS" = "install ok installed" ] || [ "$DOWNLOAD_ALL" = "true" ];
+ then
+ wget -nv "${POOL_URL}/${p}"
+ fi
+ done
+}
+
+
+[ $# -eq 0 ] && { usage 1>&2 && exit 1; }
+
+while [ $# -gt 0 ];
+do
+ case "$1" in
+ --)
+ shift
+ break
+ ;;
+ -h|--help)
+ usage
+ exit 0
+ ;;
+ --all)
+ DOWNLOAD_ALL="true"
+ shift
+ ;;
+ -*)
+ echo "Error: Unknown option '${1}'" 1>&2
+ shift
+ ;;
+ *)
+ break
+ ;;
+ esac
+done
+
+download "$@"
+MIRROR=$DEBUG_MIRROR download "$@"