summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt-pkg/contrib/md5.cc2
-rw-r--r--apt-pkg/contrib/sha1.cc2
-rw-r--r--apt-pkg/policy.cc64
-rw-r--r--apt-pkg/policy.h1
-rwxr-xr-xcmdline/apt-key15
-rw-r--r--debian/changelog7
-rw-r--r--debian/libapt-pkg4.11.symbols53
-rw-r--r--doc/apt-key.8.xml21
-rw-r--r--doc/apt-verbatim.ent6
-rw-r--r--doc/makefile1
-rwxr-xr-xtest/integration/test-pin-non-existent-package72
11 files changed, 187 insertions, 57 deletions
diff --git a/apt-pkg/contrib/md5.cc b/apt-pkg/contrib/md5.cc
index 6c60ffd74..6820d3951 100644
--- a/apt-pkg/contrib/md5.cc
+++ b/apt-pkg/contrib/md5.cc
@@ -298,7 +298,7 @@ MD5SumValue MD5Summation::Result()
}
MD5SumValue V;
- V.Set((char *)buf);
+ V.Set((unsigned char *)buf);
return V;
}
/*}}}*/
diff --git a/apt-pkg/contrib/sha1.cc b/apt-pkg/contrib/sha1.cc
index 0b1c16dc3..9a6725ef3 100644
--- a/apt-pkg/contrib/sha1.cc
+++ b/apt-pkg/contrib/sha1.cc
@@ -229,7 +229,7 @@ SHA1SumValue SHA1Summation::Result()
// Transfer over the result
SHA1SumValue Value;
- char res[20];
+ unsigned char res[20];
for (unsigned i = 0; i < 20; i++)
{
res[i] = (unsigned char)
diff --git a/apt-pkg/policy.cc b/apt-pkg/policy.cc
index 4fc272a74..be96d4c84 100644
--- a/apt-pkg/policy.cc
+++ b/apt-pkg/policy.cc
@@ -210,13 +210,20 @@ void pkgPolicy::CreatePin(pkgVersionMatch::MatchType Type,string Name,
{
if (Name.empty() == true)
{
- Pin *P = &*Defaults.insert(Defaults.end(),PkgPin());
+ Pin *P = &*Defaults.insert(Defaults.end(),Pin());
P->Type = Type;
P->Priority = Priority;
P->Data = Data;
return;
}
-
+
+ size_t found = Name.rfind(':');
+ string Arch;
+ if (found != string::npos) {
+ Arch = Name.substr(found+1);
+ Name.erase(found);
+ }
+
// Allow pinning by wildcards
// TODO: Maybe we should always prefer specific pins over non-
// specific ones.
@@ -225,32 +232,49 @@ void pkgPolicy::CreatePin(pkgVersionMatch::MatchType Type,string Name,
pkgVersionMatch match(Data, Type);
for (pkgCache::GrpIterator G = Cache->GrpBegin(); G.end() != true; ++G)
if (match.ExpressionMatches(Name, G.Name()))
- CreatePin(Type, G.Name(), Data, Priority);
+ {
+ if (Arch.empty() == false)
+ CreatePin(Type, string(G.Name()).append(":").append(Arch), Data, Priority);
+ else
+ CreatePin(Type, G.Name(), Data, Priority);
+ }
return;
}
- // Get a spot to put the pin
- pkgCache::GrpIterator Grp = Cache->FindGrp(Name);
- for (pkgCache::PkgIterator Pkg = Grp.PackageList();
- Pkg.end() != true; Pkg = Grp.NextPkg(Pkg))
+ // find the package (group) this pin applies to
+ pkgCache::GrpIterator Grp;
+ pkgCache::PkgIterator Pkg;
+ if (Arch.empty() == false)
+ Pkg = Cache->FindPkg(Name, Arch);
+ else {
+ Grp = Cache->FindGrp(Name);
+ if (Grp.end() == false)
+ Pkg = Grp.PackageList();
+ }
+
+ if (Pkg.end() == true)
{
- Pin *P = 0;
- if (Pkg.end() == false)
- P = Pins + Pkg->ID;
- else
- {
- // Check the unmatched table
- for (vector<PkgPin>::iterator I = Unmatched.begin();
- I != Unmatched.end() && P == 0; I++)
- if (I->Pkg == Name)
- P = &*I;
+ PkgPin *P = &*Unmatched.insert(Unmatched.end(),PkgPin(Name));
+ if (Arch.empty() == false)
+ P->Pkg.append(":").append(Arch);
+ P->Type = Type;
+ P->Priority = Priority;
+ P->Data = Data;
+ return;
+ }
- if (P == 0)
- P = &*Unmatched.insert(Unmatched.end(),PkgPin());
- }
+ for (; Pkg.end() != true; Pkg = Grp.NextPkg(Pkg))
+ {
+ Pin *P = Pins + Pkg->ID;
+ // the first specific stanza for a package is the ruler,
+ // all others need to be ignored
+ if (P->Type != pkgVersionMatch::None)
+ P = &*Unmatched.insert(Unmatched.end(),PkgPin(Pkg.FullName()));
P->Type = Type;
P->Priority = Priority;
P->Data = Data;
+ if (Grp.end() == true)
+ break;
}
}
/*}}}*/
diff --git a/apt-pkg/policy.h b/apt-pkg/policy.h
index e7f36d618..92d32728f 100644
--- a/apt-pkg/policy.h
+++ b/apt-pkg/policy.h
@@ -55,6 +55,7 @@ class pkgPolicy : public pkgDepCache::Policy
struct PkgPin : Pin
{
string Pkg;
+ PkgPin(string const &Pkg) : Pin(), Pkg(Pkg) {};
};
Pin *Pins;
diff --git a/cmdline/apt-key b/cmdline/apt-key
index 3838fafcd..843163f82 100755
--- a/cmdline/apt-key
+++ b/cmdline/apt-key
@@ -21,6 +21,13 @@ ARCHIVE_KEYRING_URI=""
ARCHIVE_KEYRING=/usr/share/keyrings/debian-archive-keyring.gpg
REMOVED_KEYS=/usr/share/keyrings/debian-archive-removed-keys.gpg
+requires_root() {
+ if [ "$(id -u)" -ne 0 ]; then
+ echo >&1 "ERROR: This command can only be used by root."
+ exit 1
+ fi
+}
+
add_keys_with_verify_against_master_keyring() {
ADD_KEYRING=$1
MASTER=$2
@@ -59,13 +66,14 @@ add_keys_with_verify_against_master_keyring() {
# (otherwise it does not make sense from a security POV)
net_update() {
if [ -z "$ARCHIVE_KEYRING_URI" ]; then
- echo "ERROR: no location for the archive-keyring given"
+ echo >&2 "ERROR: Your distribution is not supported in net-update as no uri for the archive-keyring is set"
exit 1
fi
+ requires_root
# in theory we would need to depend on wget for this, but this feature
# isn't useable in debian anyway as we have no keyring uri nor a master key
if ! which wget >/dev/null 2>&1; then
- echo "ERROR: an installed wget is required for a network-based update"
+ echo >&2 "ERROR: an installed wget is required for a network-based update"
exit 1
fi
if [ ! -d /var/lib/apt/keyrings ]; then
@@ -93,6 +101,7 @@ update() {
echo >&2 "Is the debian-archive-keyring package installed?"
exit 1
fi
+ requires_root
# add new keys from the package;
@@ -184,10 +193,12 @@ fi
case "$command" in
add)
+ requires_root
$GPG --quiet --batch --import "$1"
echo "OK"
;;
del|rm|remove)
+ requires_root
$GPG --quiet --batch --delete-key --yes "$1"
echo "OK"
;;
diff --git a/debian/changelog b/debian/changelog
index 73881ac54..9aeb2f809 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,4 +1,4 @@
-apt (0.8.16~exp3) experimental; urgency=low
+apt (0.8.16~exp3) UNRELEASEDexperimental; urgency=low
[ David Kalnischkies ]
* apt-pkg/pkgcache.h:
@@ -8,6 +8,11 @@ apt (0.8.16~exp3) experimental; urgency=low
- try even harder to support really big files in the fetcher by
converting (hopefully) everything to 'long long' (Closes: #632271)
+ [ Michael Vogt ]
+ * merge fixes from the debian/unstable upload
+ * merge lp:~mvo/apt/sha512-template to get fixes for the
+ sha1/md5 verifiation (closes: #632520)
+
-- David Kalnischkies <kalnischkies@gmail.com> Tue, 05 Jul 2011 15:56:42 +0200
apt (0.8.16~exp2) experimental; urgency=low
diff --git a/debian/libapt-pkg4.11.symbols b/debian/libapt-pkg4.11.symbols
index 2a41ea2c9..ce598e7b3 100644
--- a/debian/libapt-pkg4.11.symbols
+++ b/debian/libapt-pkg4.11.symbols
@@ -1229,37 +1229,45 @@ libapt-pkg.so.4.11 libapt-pkg4.11 #MINVER#
# (c++|regex|optional=std)"^std::vector<.+ >::(vector|push_back|erase|_[^ ]+)\(.+\)( const|)@Base$" 0.8.0
# (c++|regex|optional=std)"^pkgCache::(Dep|Pkg|Ver|Grp|Prv|Desc|PkgFile)Iterator\*\* std::_.+@Base$" 0.8.0
### gcc-4.5 specific
- (c++|regex|optional=std)"^char\* std::[^ ]+<.+ >::_.+@Base$" 0.8.0
- (c++|optional=inline)"FileFd::FileFd(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, FileFd::OpenMode, unsigned long)@Base" 0.8.0
- (c++|regex|optional=template)"^SPtrArray<[^ ]+>::~SPtrArray\(\)@Base$" 0.8.0
- (c++|optional=template)"SPtrArray<unsigned char>::~SPtrArray()@Base" 0.8.0
+# (c++|regex|optional=std)"^char\* std::[^ ]+<.+ >::_.+@Base$" 0.8.0
+# (c++|optional=inline)"FileFd::FileFd(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, FileFd::OpenMode, unsigned long)@Base" 0.8.0
+# (c++|regex|optional=template)"^SPtrArray<[^ ]+>::~SPtrArray\(\)@Base$" 0.8.0
+# (c++|optional=template)"SPtrArray<unsigned char>::~SPtrArray()@Base" 0.8.0
### gcc-4.6 specific
(c++|optional=template)"SPtrArray<pkgCache::Version*>::~SPtrArray()@Base" 0.8.0
(c++|regex|optional=std)"^std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<char( const|)\*>\(.+\)@Base$" 0.8.0
(c++|regex|optional=std)"^std::vector<DiffInfo, .+@Base$" 0.8.0
(c++|regex|optional=std)"^std::vector<.+ >::(vector|push_back|erase|_[^ ]+)\(.+\)( const|)@Base$" 0.8.0
- (c++|optional=strange)"pkgCache::VerIterator::VerIterator(pkgCache&, pkgCache::Version*)@Base" 0.8.0
+# (c++|optional=strange)"pkgCache::VerIterator::VerIterator(pkgCache&, pkgCache::Version*)@Base" 0.8.0
+### architecture specific: va_list
+ (arch=armel armhf|c++)"pkgAcqMethod::PrintStatus(char const*, char const*, std::__va_list&) const@Base" 0.8.15~exp1
+ (arch=i386 hurd-i386 kfreebsd-i386|c++)"pkgAcqMethod::PrintStatus(char const*, char const*, char*&) const@Base" 0.8.15~exp1
+ (arch=hppa ia64 mips mipsel sparc sparc64|c++)"pkgAcqMethod::PrintStatus(char const*, char const*, void*&) const@Base" 0.8.15~exp1
+ (arch=amd64 kfreebsd-amd64 powerpc powerpcspe s390|c++)"pkgAcqMethod::PrintStatus(char const*, char const*, __va_list_tag (&) [1]) const@Base" 0.8.15~exp1
+ (arch=sh4|c++)"pkgAcqMethod::PrintStatus(char const*, char const*, __builtin_va_list&) const@Base" 0.8.15~exp1
+ (arch=alpha|c++)"pkgAcqMethod::PrintStatus(char const*, char const*, __va_list_tag&) const@Base" 0.8.15~exp1
### architecture specific: va_list & size_t
- (arch=i386 hurd-i386 kfreebsd-i386|c++|optional=private)"GlobalError::Insert(GlobalError::MsgType, char const*, char*&, unsigned int&)@Base" 0.8.11.4 1
- (arch=armel armhf|c++|optional=private)"GlobalError::Insert(GlobalError::MsgType, char const*, std::__va_list&, unsigned int&)@Base" 0.8.11.4 1
- (arch=alpha|c++|optional=private)"GlobalError::Insert(GlobalError::MsgType, char const*, __va_list_tag&, unsigned long&)@Base" 0.8.11.4 1
- (arch=powerpc powerpcspe|c++|optional=private)"GlobalError::Insert(GlobalError::MsgType, char const*, __va_list_tag (&) [1], unsigned int&)@Base" 0.8.11.4 1
- (arch=amd64 kfreebsd-amd64 s390|c++|optional=private)"GlobalError::Insert(GlobalError::MsgType, char const*, __va_list_tag (&) [1], unsigned long&)@Base" 0.8.11.4 1
- (arch=hppa mipsel sparc|c++|optional=private)"GlobalError::Insert(GlobalError::MsgType, char const*, void*&, unsigned int&)@Base" 0.8.11.4 1
- (arch=ia64 sparc64|c++|optional=private)"GlobalError::Insert(GlobalError::MsgType, char const*, void*&, unsigned long&)@Base" 0.8.11.4 1
- (arch=sh4|c++|optional=private)"GlobalError::Insert(GlobalError::MsgType, char const*, __builtin_va_list&, unsigned int&)@Base" 0.8.11.4 1
- (arch=i386 hurd-i386 kfreebsd-i386|c++|optional=private)"GlobalError::InsertErrno(GlobalError::MsgType, char const*, char const*, char*&, int, unsigned int&)@Base" 0.8.11.4 1
- (arch=armel armhf|c++|optional=private)"GlobalError::InsertErrno(GlobalError::MsgType, char const*, char const*, std::__va_list&, int, unsigned int&)@Base" 0.8.11.4 1
- (arch=alpha|c++|optional=private)"GlobalError::InsertErrno(GlobalError::MsgType, char const*, char const*, __va_list_tag&, int, unsigned long&)@Base" 0.8.11.4 1
- (arch=powerpc powerpcspe|c++|optional=private)"GlobalError::InsertErrno(GlobalError::MsgType, char const*, char const*, __va_list_tag (&) [1], int, unsigned int&)@Base" 0.8.11.4 1
- (arch=amd64 kfreebsd-amd64 s390|c++|optional=private)"GlobalError::InsertErrno(GlobalError::MsgType, char const*, char const*, __va_list_tag (&) [1], int, unsigned long&)@Base" 0.8.11.4 1
- (arch=hppa mipsel sparc|c++|optional=private)"GlobalError::InsertErrno(GlobalError::MsgType, char const*, char const*, void*&, int, unsigned int&)@Base" 0.8.11.4 1
+ (arch=i386 hurd-i386 kfreebsd-i386|c++|optional=private)"GlobalError::Insert(GlobalError::MsgType, char const*, char*&, unsigned int&)@Base" 0.8.11.4
+ (arch=armel armhf|c++|optional=private)"GlobalError::Insert(GlobalError::MsgType, char const*, std::__va_list&, unsigned int&)@Base" 0.8.11.4
+ (arch=alpha|c++|optional=private)"GlobalError::Insert(GlobalError::MsgType, char const*, __va_list_tag&, unsigned long&)@Base" 0.8.11.4
+ (arch=powerpc powerpcspe|c++|optional=private)"GlobalError::Insert(GlobalError::MsgType, char const*, __va_list_tag (&) [1], unsigned int&)@Base" 0.8.11.4
+ (arch=amd64 kfreebsd-amd64 s390|c++|optional=private)"GlobalError::Insert(GlobalError::MsgType, char const*, __va_list_tag (&) [1], unsigned long&)@Base" 0.8.11.4
+ (arch=hppa mips mipsel sparc|c++|optional=private)"GlobalError::Insert(GlobalError::MsgType, char const*, void*&, unsigned int&)@Base" 0.8.11.4
+ (arch=ia64 sparc64|c++|optional=private)"GlobalError::Insert(GlobalError::MsgType, char const*, void*&, unsigned long&)@Base" 0.8.11.4
+ (arch=sh4|c++|optional=private)"GlobalError::Insert(GlobalError::MsgType, char const*, __builtin_va_list&, unsigned int&)@Base" 0.8.11.4
+
+ (arch=i386 hurd-i386 kfreebsd-i386|c++|optional=private)"GlobalError::InsertErrno(GlobalError::MsgType, char const*, char const*, char*&, int, unsigned int&)@Base" 0.8.11.4
+ (arch=armel armhf|c++|optional=private)"GlobalError::InsertErrno(GlobalError::MsgType, char const*, char const*, std::__va_list&, int, unsigned int&)@Base" 0.8.11.4
+ (arch=alpha|c++|optional=private)"GlobalError::InsertErrno(GlobalError::MsgType, char const*, char const*, __va_list_tag&, int, unsigned long&)@Base" 0.8.11.4
+ (arch=powerpc powerpcspe|c++|optional=private)"GlobalError::InsertErrno(GlobalError::MsgType, char const*, char const*, __va_list_tag (&) [1], int, unsigned int&)@Base" 0.8.11.4
+ (arch=amd64 kfreebsd-amd64 s390|c++|optional=private)"GlobalError::InsertErrno(GlobalError::MsgType, char const*, char const*, __va_list_tag (&) [1], int, unsigned long&)@Base" 0.8.11.4
+ (arch=hppa mips mipsel sparc|c++|optional=private)"GlobalError::InsertErrno(GlobalError::MsgType, char const*, char const*, void*&, int, unsigned int&)@Base" 0.8.11.4
(arch=ia64 sparc64|c++|optional=private)"GlobalError::InsertErrno(GlobalError::MsgType, char const*, char const*, void*&, int, unsigned long&)@Base" 0.8.11.4 1
- (arch=sh4|c++|optional=private)"GlobalError::InsertErrno(GlobalError::MsgType, char const*, char const*, __builtin_va_list&, int, unsigned int&)@Base" 0.8.11.4 1
+ (arch=sh4|c++|optional=private)"GlobalError::InsertErrno(GlobalError::MsgType, char const*, char const*, __builtin_va_list&, int, unsigned int&)@Base" 0.8.11.4
### architecture specific: size_t
- (arch=i386 armel armhf hppa hurd-i386 kfreebsd-i386 mipsel powerpc powerpcspe sh4 sparc|c++)"_strtabexpand(char*, unsigned int)@Base" 0.8.0
+ (arch=i386 armel armhf hppa hurd-i386 kfreebsd-i386 mips mipsel powerpc powerpcspe sh4 sparc|c++)"_strtabexpand(char*, unsigned int)@Base" 0.8.0
(arch=alpha amd64 ia64 kfreebsd-amd64 s390 sparc64|c++)"_strtabexpand(char*, unsigned long)@Base" 0.8.0
- (arch=i386 armel armhf hppa hurd-i386 kfreebsd-i386 mipsel powerpc powerpcspe sh4 sparc|c++)"indexRecords::parseSumData(char const*&, char const*, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, unsigned int&)@Base" 0.8.0
+ (arch=i386 armel armhf hppa hurd-i386 kfreebsd-i386 mips mipsel powerpc powerpcspe sh4 sparc|c++)"indexRecords::parseSumData(char const*&, char const*, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, unsigned int&)@Base" 0.8.0
(arch=alpha amd64 ia64 kfreebsd-amd64 s390 sparc64|c++)"indexRecords::parseSumData(char const*&, char const*, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, unsigned long&)@Base" 0.8.0
### try to ignore std:: template instances
(c++|regex|optional=std)"^(void |)std::[^ ]+<.+ >::(_|~).+\(.*\)@Base$" 0.8.0
@@ -1318,5 +1326,4 @@ libapt-pkg.so.4.11 libapt-pkg4.11 #MINVER#
(c++|optional=private)"PrintMode(char)@Base" 0.8.13.2
(c++)"pkgDepCache::IsModeChangeOk(pkgDepCache::ModeList, pkgCache::PkgIterator const&, unsigned long, bool)@Base" 0.8.13.2
(c++)"pkgPackageManager::SmartUnPack(pkgCache::PkgIterator, bool)@Base" 0.8.15~exp1
- (c++)"pkgAcqMethod::PrintStatus(char const*, char const*, char*&) const@Base" 0.8.15~exp1
(c++)"pkgCache::DepIterator::IsNegative() const@Base" 0.8.15~exp1
diff --git a/doc/apt-key.8.xml b/doc/apt-key.8.xml
index 9bfab84b6..f17f0c45e 100644
--- a/doc/apt-key.8.xml
+++ b/doc/apt-key.8.xml
@@ -128,9 +128,10 @@
<listitem>
<para>
- Update the local keyring with the keyring of Debian archive
- keys and removes from the keyring the archive keys which are no
- longer valid.
+ Update the local keyring with the archive keyring and remove from
+ the local keyring the archive keys which are no longer valid.
+ The archive keyring is shipped in the <literal>archive-keyring</literal> package of your
+ distribution, e.g. the <literal>debian-archive-keyring</literal> package in Debian.
</para>
@@ -141,12 +142,14 @@
<listitem>
<para>
- Update the local keyring with the keys of a key server
- and removes from the keyring the archive keys which are no
- longer valid. This requires an installed wget and an APT
- build configured to have a server to fetch from. APT in
- Debian does not support this command, but Ubuntu's APT
- does.
+ Work similar to the <command>update</command> command above, but get the
+ archive keyring from an URI instead and validate it against a master key.
+
+ This requires an installed &wget; and an APT build configured to have
+ a server to fetch from and a master keyring to validate.
+
+ APT in Debian does not support this command and relies on
+ <command>update</command> instead, but Ubuntu's APT does.
</para>
diff --git a/doc/apt-verbatim.ent b/doc/apt-verbatim.ent
index a194a9d0d..14cd70e89 100644
--- a/doc/apt-verbatim.ent
+++ b/doc/apt-verbatim.ent
@@ -148,6 +148,12 @@
</citerefentry>"
>
+<!ENTITY wget "<citerefentry>
+ <refentrytitle><command>wget</command></refentrytitle>
+ <manvolnum>1</manvolnum>
+ </citerefentry>"
+>
+
<!-- Boiler plate docinfo section -->
<!ENTITY apt-email "
<address>
diff --git a/doc/makefile b/doc/makefile
index 8a889c94c..4fcf3bd10 100644
--- a/doc/makefile
+++ b/doc/makefile
@@ -101,6 +101,7 @@ $(BUILD)/doc/Doxyfile: Doxyfile.in
$(BUILD)/doc/doxygen-stamp: $(DOXYGEN_SOURCES) $(BUILD)/doc/Doxyfile
rm -fr $(BUILD)/doc/doxygen
+ mkdir $(BUILD)/doc/doxygen # some versions seem to not create this directory #628799
$(DOXYGEN) $(BUILD)/doc/Doxyfile
touch $(BUILD)/doc/doxygen-stamp
diff --git a/test/integration/test-pin-non-existent-package b/test/integration/test-pin-non-existent-package
new file mode 100755
index 000000000..c91e77844
--- /dev/null
+++ b/test/integration/test-pin-non-existent-package
@@ -0,0 +1,72 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+setupenvironment
+configarchitecture "i386"
+
+insertpackage 'unstable' 'apt' 'i386' '0.8.15'
+insertpackage 'unstable' 'arch' 'i386' '1.0'
+
+setupaptarchive
+
+testcandidate() {
+ msgtest "Test that the Candidate for $1 is" $2
+ if [ "$(aptcache policy $1 | grep '^ Candidate:')" = " Candidate: $2" ]; then
+ msgpass
+ else
+ echo
+ aptcache policy $1
+ msgfail
+ fi
+}
+
+testcandidate apt '0.8.15'
+testequal 'N: Unable to locate package doesntexist' aptcache policy doesntexist -q=0
+testequal 'Reading package lists...
+Building dependency tree...
+0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.' aptget dist-upgrade
+
+echo 'Package: apt
+Pin: release a=unstable
+Pin-Priority: -1' > rootdir/etc/apt/preferences
+
+testcandidate apt '(none)'
+testequal 'N: Unable to locate package doesntexist' aptcache policy doesntexist -q=0
+testequal 'Reading package lists...
+Building dependency tree...
+0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.' aptget dist-upgrade
+
+echo '
+Package: doesntexist
+Pin: release a=unstable
+Pin-Priority: 1000' >> rootdir/etc/apt/preferences
+
+testcandidate apt '(none)'
+
+echo '
+Package: apt
+Pin: release a=unstable
+Pin-Priority: 1000' >> rootdir/etc/apt/preferences
+
+testcandidate apt '(none)'
+testequal 'N: Unable to locate package doesntexist' aptcache policy doesntexist -q=0
+
+testequal 'Reading package lists...
+Building dependency tree...
+0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.' aptget dist-upgrade
+
+echo 'Package: arch:amd64
+Pin: release a=unstable
+Pin-Priority: -1' > rootdir/etc/apt/preferences
+
+testcandidate arch '1.0'
+
+echo '
+Package: arch:i386
+Pin: release a=unstable
+Pin-Priority: -1' >> rootdir/etc/apt/preferences
+
+testcandidate arch '(none)'
+