]> git.saurik.com Git - apt.git/commitdiff
Merge branch 'debian/jessie' into debian/experimental
authorDavid Kalnischkies <david@kalnischkies.de>
Sat, 18 Apr 2015 23:24:46 +0000 (01:24 +0200)
committerDavid Kalnischkies <david@kalnischkies.de>
Sat, 18 Apr 2015 23:27:31 +0000 (01:27 +0200)
Conflicts:
apt-pkg/acquire-item.cc
cmdline/apt-key.in
methods/https.cc
test/integration/test-apt-key
test/integration/test-multiarch-foreign

1  2 
apt-pkg/contrib/strutl.h
apt-pkg/deb/deblistparser.cc
apt-pkg/deb/dpkgpm.cc
cmdline/apt-key.in
configure.ac
debian/changelog
test/integration/test-apt-key
test/integration/test-multiarch-foreign
test/integration/test-specific-architecture-dependencies

diff --combined apt-pkg/contrib/strutl.h
index e20ddca9c45d336694d004525dec27784a4f6f9a,f4f80834bccc07749300b5ff8dce54594777a07a..d64270aaf3d0714de2297000b1ab31b9b8fca9c2
@@@ -40,7 -40,6 +40,7 @@@ namespace APT 
     namespace String {
        std::string Strip(const std::string &s);
        bool Endswith(const std::string &s, const std::string &ending);
 +      bool Startswith(const std::string &s, const std::string &starting);
     }
  }
  
@@@ -73,7 -72,6 +73,7 @@@ bool ReadMessages(int Fd, std::vector<s
  bool StrToNum(const char *Str,unsigned long &Res,unsigned Len,unsigned Base = 0);
  bool StrToNum(const char *Str,unsigned long long &Res,unsigned Len,unsigned Base = 0);
  bool Base256ToNum(const char *Str,unsigned long &Res,unsigned int Len);
 +bool Base256ToNum(const char *Str,unsigned long long &Res,unsigned int Len);
  bool Hex2Num(const std::string &Str,unsigned char *Num,unsigned int Length);
  
  // input changing string split
@@@ -81,7 -79,7 +81,7 @@@ bool TokSplitString(char Tok,char *Inpu
                    unsigned long ListMax);
  
  // split a given string by a char
- std::vector<std::string> VectorizeString(std::string const &haystack, char const &split) APT_CONST;
+ std::vector<std::string> VectorizeString(std::string const &haystack, char const &split) APT_PURE;
  
  /* \brief Return a vector of strings from string "input" where "sep"
   * is used as the delimiter string.
@@@ -153,9 -151,9 +153,9 @@@ inline const char *DeNull(const char *s
  class URI
  {
     void CopyFrom(const std::string &From);
 -               
 +
     public:
 -   
 +
     std::string Access;
     std::string User;
     std::string Password;
index 49bc3adfc57d0f9453907ca8c5fea57610888774,213235c2b16b217b1ca31fea7bb23d77fe10ac89..b80b57bc46c3ff04059e01c1abc4587b74a2e77d
@@@ -58,6 -58,18 +58,6 @@@ debListParser::debListParser(FileFd *Fi
     MultiArchEnabled = Architectures.size() > 1;
  }
                                                                        /*}}}*/
 -// ListParser::UniqFindTagWrite - Find the tag and write a unq string /*{{{*/
 -// ---------------------------------------------------------------------
 -/* */
 -unsigned long debListParser::UniqFindTagWrite(const char *Tag)
 -{
 -   const char *Start;
 -   const char *Stop;
 -   if (Section.Find(Tag,Start,Stop) == false)
 -      return 0;
 -   return WriteUniqString(Start,Stop - Start);
 -}
 -                                                                      /*}}}*/
  // ListParser::Package - Return the package name                      /*{{{*/
  // ---------------------------------------------------------------------
  /* This is to return the name of the package this section describes */
@@@ -132,69 -144,9 +132,69 @@@ unsigned char debListParser::ParseMulti
  /* */
  bool debListParser::NewVersion(pkgCache::VerIterator &Ver)
  {
 +   const char *Start;
 +   const char *Stop;
 +
     // Parse the section
 -   unsigned long const idxSection = UniqFindTagWrite("Section");
 -   Ver->Section = idxSection;
 +   if (Section.Find("Section",Start,Stop) == true)
 +   {
 +      map_stringitem_t const idx = StoreString(pkgCacheGenerator::SECTION, Start, Stop - Start);
 +      Ver->Section = idx;
 +   }
 +#if APT_PKG_ABI >= 413
 +   // Parse the source package name
 +   pkgCache::GrpIterator const G = Ver.ParentPkg().Group();
 +   Ver->SourcePkgName = G->Name;
 +   Ver->SourceVerStr = Ver->VerStr;
 +   if (Section.Find("Source",Start,Stop) == true)
 +   {
 +      const char * const Space = (const char * const) memchr(Start, ' ', Stop - Start);
 +      pkgCache::VerIterator V;
 +
 +      if (Space != NULL)
 +      {
 +       Stop = Space;
 +       const char * const Open = (const char * const) memchr(Space, '(', Stop - Space);
 +       if (likely(Open != NULL))
 +       {
 +          const char * const Close = (const char * const) memchr(Open, ')', Stop - Open);
 +          if (likely(Close != NULL))
 +          {
 +             std::string const version(Open + 1, (Close - Open) - 1);
 +             if (version != Ver.VerStr())
 +             {
 +                map_stringitem_t const idx = StoreString(pkgCacheGenerator::VERSIONNUMBER, version);
 +                Ver->SourceVerStr = idx;
 +             }
 +          }
 +       }
 +      }
 +
 +      std::string const pkgname(Start, Stop - Start);
 +      if (pkgname != G.Name())
 +      {
 +       for (pkgCache::PkgIterator P = G.PackageList(); P.end() == false; P = G.NextPkg(P))
 +       {
 +          for (V = P.VersionList(); V.end() == false; ++V)
 +          {
 +             if (pkgname == V.SourcePkgName())
 +             {
 +                Ver->SourcePkgName = V->SourcePkgName;
 +                break;
 +             }
 +          }
 +          if (V.end() == false)
 +             break;
 +       }
 +       if (V.end() == true)
 +       {
 +          map_stringitem_t const idx = StoreString(pkgCacheGenerator::PKGNAME, pkgname);
 +          Ver->SourcePkgName = idx;
 +       }
 +      }
 +   }
 +#endif
 +
     Ver->MultiArch = ParseMultiArch(true);
     // Archive Size
     Ver->Size = Section.FindULL("Size");
     Ver->InstalledSize *= 1024;
  
     // Priority
 -   const char *Start;
 -   const char *Stop;
     if (Section.Find("Priority",Start,Stop) == true)
 -   {      
 +   {
        if (GrabWord(string(Start,Stop-Start),PrioList,Ver->Priority) == false)
         Ver->Priority = pkgCache::State::Extra;
     }
  /* This is to return the string describing the package in debian
     form. If this returns the blank string then the entry is assumed to
     only describe package properties */
 -string debListParser::Description()
 +string debListParser::Description(std::string const &lang)
  {
 -   string const lang = DescriptionLanguage();
     if (lang.empty())
        return Section.FindS("Description");
     else
        return Section.FindS(string("Description-").append(lang).c_str());
  }
 -                                                                        /*}}}*/
 -// ListParser::DescriptionLanguage - Return the description lang string       /*{{{*/
 -// ---------------------------------------------------------------------
 -/* This is to return the string describing the language of
 -   description. If this returns the blank string then the entry is
 -   assumed to describe original description. */
 -string debListParser::DescriptionLanguage()
 +                                                                      /*}}}*/
 +// ListParser::AvailableDescriptionLanguages                          /*{{{*/
 +std::vector<std::string> debListParser::AvailableDescriptionLanguages()
  {
 -   if (Section.FindS("Description").empty() == false)
 -      return "";
 -
 -   std::vector<string> const lang = APT::Configuration::getLanguages(true);
 -   for (std::vector<string>::const_iterator l = lang.begin();
 -      l != lang.end(); ++l)
 -      if (Section.FindS(string("Description-").append(*l).c_str()).empty() == false)
 -       return *l;
 -
 -   return "";
 +   std::vector<std::string> const understood = APT::Configuration::getLanguages();
 +   std::vector<std::string> avail;
 +   if (Section.Exists("Description") == true)
 +      avail.push_back("");
 +   for (std::vector<std::string>::const_iterator lang = understood.begin(); lang != understood.end(); ++lang)
 +   {
 +      std::string const tagname = "Description-" + *lang;
 +      if (Section.Exists(tagname.c_str()) == true)
 +       avail.push_back(*lang);
 +   }
 +   return avail;
  }
 -                                                                        /*}}}*/
 -// ListParser::Description - Return the description_md5 MD5SumValue   /*{{{*/
 +                                                                      /*}}}*/
 +// ListParser::Description_md5 - Return the description_md5 MD5SumValue       /*{{{*/
  // ---------------------------------------------------------------------
  /* This is to return the md5 string to allow the check if it is the right
     description. If no Description-md5 is found in the section it will be
@@@ -276,7 -234,7 +276,7 @@@ MD5SumValue debListParser::Description_
     string const value = Section.FindS("Description-md5");
     if (value.empty() == true)
     {
 -      std::string const desc = Description() + "\n";
 +      std::string const desc = Description("") + "\n";
        if (desc == "\n")
         return MD5SumValue();
  
  bool debListParser::UsePackage(pkgCache::PkgIterator &Pkg,
                               pkgCache::VerIterator &Ver)
  {
 -   if (Pkg->Section == 0)
 -   {
 -      unsigned long const idxSection = UniqFindTagWrite("Section");
 -      Pkg->Section = idxSection;
 -   }
 -
     string const static myArch = _config->Find("APT::Architecture");
     // Possible values are: "all", "native", "installed" and "none"
     // The "installed" mode is handled by ParseStatus(), See #544481 and friends.
@@@ -806,7 -770,7 +806,7 @@@ bool debListParser::ParseDepends(pkgCac
         if (NewDepends(Ver,Package,"none",Version,Op,Type) == false)
            return false;
        }
-       else if (MultiArchEnabled == true && found != string::npos &&
+       else if (found != string::npos &&
               strcmp(Package.c_str() + found, ":any") != 0)
        {
         string Arch = Package.substr(found+1, string::npos);
@@@ -853,16 -817,10 +853,16 @@@ bool debListParser::ParseProvides(pkgCa
        while (1)
        {
         Start = ParseDepends(Start,Stop,Package,Version,Op);
 +       const size_t archfound = Package.rfind(':');
         if (Start == 0)
            return _error->Error("Problem parsing Provides line");
         if (Op != pkgCache::Dep::NoOp && Op != pkgCache::Dep::Equals) {
            _error->Warning("Ignoring Provides line with non-equal DepCompareOp for package %s", Package.c_str());
 +       } else if (archfound != string::npos) {
 +          string OtherArch = Package.substr(archfound+1, string::npos);
 +          Package = Package.substr(0, archfound);
 +          if (NewProvides(Ver, Package, OtherArch, Version) == false)
 +             return false;
         } else if ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign) {
            if (NewProvidesAllArch(Ver, Package, Version) == false)
               return false;
@@@ -959,7 -917,7 +959,7 @@@ bool debListParser::LoadReleaseInfo(pkg
  {
     // apt-secure does no longer download individual (per-section) Release
     // file. to provide Component pinning we use the section name now
 -   map_ptrloc const storage = WriteUniqString(component);
 +   map_stringitem_t const storage = StoreString(pkgCacheGenerator::MIXED, component);
     FileI->Component = storage;
  
     pkgTagFile TagFile(&File, File.Size());
        return false;
  
     std::string data;
 -   #define APT_INRELEASE(TAG, STORE) \
 +   #define APT_INRELEASE(TYPE, TAG, STORE) \
     data = Section.FindS(TAG); \
     if (data.empty() == false) \
     { \
 -      map_ptrloc const storage = WriteUniqString(data); \
 +      map_stringitem_t const storage = StoreString(pkgCacheGenerator::TYPE, data); \
        STORE = storage; \
     }
 -   APT_INRELEASE("Suite", FileI->Archive)
 -   APT_INRELEASE("Component", FileI->Component)
 -   APT_INRELEASE("Version", FileI->Version)
 -   APT_INRELEASE("Origin", FileI->Origin)
 -   APT_INRELEASE("Codename", FileI->Codename)
 -   APT_INRELEASE("Label", FileI->Label)
 +   APT_INRELEASE(MIXED, "Suite", FileI->Archive)
 +   APT_INRELEASE(MIXED, "Component", FileI->Component)
 +   APT_INRELEASE(VERSIONNUMBER, "Version", FileI->Version)
 +   APT_INRELEASE(MIXED, "Origin", FileI->Origin)
 +   APT_INRELEASE(MIXED, "Codename", FileI->Codename)
 +   APT_INRELEASE(MIXED, "Label", FileI->Label)
     #undef APT_INRELEASE
     Section.FindFlag("NotAutomatic", FileI->Flags, pkgCache::Flag::NotAutomatic);
     Section.FindFlag("ButAutomaticUpgrades", FileI->Flags, pkgCache::Flag::ButAutomaticUpgrades);
@@@ -1000,7 -958,7 +1000,7 @@@ unsigned char debListParser::GetPrio(st
     return Out;
  }
                                                                        /*}}}*/
 -#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
 +#if APT_PKG_ABI >= 413
  bool debListParser::SameVersion(unsigned short const Hash,            /*{{{*/
        pkgCache::VerIterator const &Ver)
  {
  }
                                                                        /*}}}*/
  #endif
 +
 +
 +debDebFileParser::debDebFileParser(FileFd *File, std::string const &DebFile)
 +   : debListParser(File, ""), DebFile(DebFile)
 +{
 +}
 +
 +bool debDebFileParser::UsePackage(pkgCache::PkgIterator &Pkg,
 +                                  pkgCache::VerIterator &Ver)
 +{
 +   bool res = debListParser::UsePackage(Pkg, Ver);
 +   // we use the full file path as a provides so that the file is found
 +   // by its name
 +   if(NewProvidesAllArch(Ver, DebFile, Ver.VerStr()) == false)
 +      return false;
 +   return res;
 +}
 +
 +debListParser::~debListParser() {}
diff --combined apt-pkg/deb/dpkgpm.cc
index 09bd9149f4bb93fc6ce3348ebd3edad50d562eac,82e045fd3ef29edbde021bb778f7d8a1b2aee313..a7a66c75d76273762ca2eb3d9e993403486b8d6d
@@@ -203,10 -203,18 +203,10 @@@ pkgCache::VerIterator FindNowVersion(co
  {
     pkgCache::VerIterator Ver;
     for (Ver = Pkg.VersionList(); Ver.end() == false; ++Ver)
 -   {
 -      pkgCache::VerFileIterator Vf = Ver.FileList();
 -      pkgCache::PkgFileIterator F = Vf.File();
 -      for (F = Vf.File(); F.end() == false; ++F)
 -      {
 -         if (F && F.Archive())
 -         {
 -            if (strcmp(F.Archive(), "now")) 
 -               return Ver;
 -         }
 -      }
 -   }
 +      for (pkgCache::VerFileIterator Vf = Ver.FileList(); Vf.end() == false; ++Vf)
 +       for (pkgCache::PkgFileIterator F = Vf.File(); F.end() == false; ++F)
 +          if (F->Archive != 0 && strcmp(F.Archive(), "now") == 0)
 +             return Ver;
     return Ver;
  }
                                                                        /*}}}*/
@@@ -526,7 -534,7 +526,7 @@@ bool pkgDPkgPM::RunScriptsWithPkgs(cons
  void pkgDPkgPM::DoStdin(int master)
  {
     unsigned char input_buf[256] = {0,}; 
 -   ssize_t len = read(0, input_buf, sizeof(input_buf));
 +   ssize_t len = read(STDIN_FILENO, input_buf, sizeof(input_buf));
     if (len)
        FileFd::Write(master, input_buf, len);
     else
@@@ -1049,6 -1057,7 +1049,6 @@@ void pkgDPkgPM::BuildPackagesProgressMa
     ++PackagesTotal;
  }
                                                                          /*}}}*/
 -#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR < 13)
  bool pkgDPkgPM::Go(int StatusFd)
  {
     APT::Progress::PackageManager *progress = NULL;
     else
        progress = new APT::Progress::PackageManagerProgressFd(StatusFd);
     
 -   return GoNoABIBreak(progress);
 +   return Go(progress);
  }
 -#endif
  
  void pkgDPkgPM::StartPtyMagic()
  {
@@@ -1213,7 -1223,11 +1213,7 @@@ void pkgDPkgPM::StopPtyMagic(
   * through to human readable (and i10n-able)
   * names and calculates a percentage for each step.
   */
 -#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
  bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
 -#else
 -bool pkgDPkgPM::GoNoABIBreak(APT::Progress::PackageManager *progress)
 -#endif
  {
     pkgPackageManager::SigINTStop = false;
     d->progress = progress;
@@@ -1702,7 -1716,7 +1702,7 @@@ void pkgDPkgPM::WriteApportReport(cons
     if (apportPkg.end() == true || apportPkg->CurrentVer == 0)
        return;
  
 -   string pkgname, reportfile, srcpkgname, pkgver, arch;
 +   string pkgname, reportfile, pkgver, arch;
     string::size_type pos;
     FILE *report;
  
     if (Ver.end() == true)
        return;
     pkgver = Ver.VerStr() == NULL ? "unknown" : Ver.VerStr();
 -   pkgRecords Recs(Cache);
 -   pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList());
 -   srcpkgname = Parse.SourcePkg();
 -   if(srcpkgname.empty())
 -      srcpkgname = pkgname;
  
     // if the file exists already, we check:
     // - if it was reported already (touched by apport). 
     time_t now = time(NULL);
     fprintf(report, "Date: %s" , ctime(&now));
     fprintf(report, "Package: %s %s\n", pkgname.c_str(), pkgver.c_str());
 +#if APT_PKG_ABI >= 413
 +   fprintf(report, "SourcePackage: %s\n", Ver.SourcePkgName());
 +#else
 +   pkgRecords Recs(Cache);
 +   pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList());
 +   std::string srcpkgname = Parse.SourcePkg();
 +   if(srcpkgname.empty())
 +      srcpkgname = pkgname;
     fprintf(report, "SourcePackage: %s\n", srcpkgname.c_str());
 +#endif
     fprintf(report, "ErrorMessage:\n %s\n", errormsg);
  
     // ensure that the log is flushed
        }
     }
  
-    // log the ordering 
-    const char *ops_str[] = {"Install", "Configure","Remove","Purge"};
+    // log the ordering, see dpkgpm.h and the "Ops" enum there
+    const char *ops_str[] = {
+       "Install",
+       "Configure",
+       "Remove",
+       "Purge",
+       "ConfigurePending",
+       "TriggersPending",
+    };
     fprintf(report, "AptOrdering:\n");
     for (vector<Item>::iterator I = List.begin(); I != List.end(); ++I)
        if ((*I).Pkg != NULL)
diff --combined cmdline/apt-key.in
index cf0b9a96f75960081d8a8bc2afb8dc5d08a2bca0,1da311d351212c5a6b2704442995943e5ed39262..2a66ad74d182a805c5a62f410ab2a3857fc67ba8
@@@ -3,6 -3,29 +3,6 @@@
  set -e
  unset GREP_OPTIONS
  
 -GPG_CMD="gpg --ignore-time-conflict --no-options --no-default-keyring"
 -
 -# gpg needs (in different versions more or less) files to function correctly,
 -# so we give it its own homedir and generate some valid content for it
 -GPGHOMEDIR="$(mktemp -d)"
 -CURRENTTRAP="${CURRENTTRAP} rm -rf '${GPGHOMEDIR}';"
 -trap "${CURRENTTRAP}" 0 HUP INT QUIT ILL ABRT FPE SEGV PIPE TERM
 -chmod 700 "$GPGHOMEDIR"
 -# We don't use a secret keyring, of course, but gpg panics and
 -# implodes if there isn't one available - and writeable for imports
 -SECRETKEYRING="${GPGHOMEDIR}/secring.gpg"
 -touch $SECRETKEYRING
 -GPG_CMD="$GPG_CMD --homedir $GPGHOMEDIR"
 -# create the trustdb with an (empty) dummy keyring
 -# older gpgs required it, newer gpgs even warn that it isn't needed,
 -# but require it nonetheless for some commands, so we just play safe
 -# here for the foreseeable future and create a dummy one
 -$GPG_CMD --quiet --check-trustdb --keyring $SECRETKEYRING >/dev/null 2>&1
 -# tell gpg that it shouldn't try to maintain a trustdb file
 -GPG_CMD="$GPG_CMD --no-auto-check-trustdb --trust-model always"
 -
 -GPG="$GPG_CMD"
 -
  APT_DIR="/"
  eval $(apt-config shell APT_DIR Dir)
  
@@@ -14,26 -37,22 +14,26 @@@ REMOVED_KEYS='&keyring-removed-filename
  eval $(apt-config shell REMOVED_KEYS APT::Key::RemovedKeys)
  ARCHIVE_KEYRING_URI='&keyring-uri;'
  eval $(apt-config shell ARCHIVE_KEYRING_URI APT::Key::ArchiveKeyringURI)
 -TMP_KEYRING=${APT_DIR}/var/lib/apt/keyrings/maybe-import-keyring.gpg
 +
 +aptkey_echo() { echo "$@"; }
  
  requires_root() {
        if [ "$(id -u)" -ne 0 ]; then
 -              echo >&1 "ERROR: This command can only be used by root."
 +              echo >&2 "ERROR: This command can only be used by root."
                exit 1
        fi
  }
  
 -# gpg defaults to mode 0600 for new keyrings. Create one with 0644 instead.
 -init_keyring() {
 -    for path; do
 -        if ! [ -e "$path" ]; then
 -            touch -- "$path"
 -            chmod 0644 -- "$path"
 -        fi
 +get_fingerprints_of_keyring() {
 +    $GPG_CMD --keyring "$1" --with-colons --fingerprint | while read publine; do
 +      # search for a public key
 +      if [ "${publine%%:*}" != 'pub' ]; then continue; fi
 +      # search for the associated fingerprint (should be the very next line)
 +      while read fprline; do
 +         if [ "${fprline%%:*}" = 'sub' ]; then break; # should never happen
 +         elif [ "${fprline%%:*}" != 'fpr' ]; then continue; fi
 +         echo "$fprline" | cut -d':' -f 10
 +      done
      done
  }
  
@@@ -42,11 -61,11 +42,11 @@@ add_keys_with_verify_against_master_key
      MASTER=$2
  
      if [ ! -f "$ADD_KEYRING" ]; then
 -      echo "ERROR: '$ADD_KEYRING' not found"
 +      echo >&2 "ERROR: '$ADD_KEYRING' not found"
        return
 -    fi 
 +    fi
      if [ ! -f "$MASTER" ]; then
 -      echo "ERROR: '$MASTER' not found"
 +      echo >&2 "ERROR: '$MASTER' not found"
        return
      fi
  
@@@ -54,7 -73,7 +54,7 @@@
      # is honored. so:
      #   all keys that are exported must have a valid signature
      #   from a key in the $distro-master-keyring
 -    add_keys=`$GPG_CMD --keyring $ADD_KEYRING --with-colons --list-keys | grep ^pub | cut -d: -f5`
 +    add_keys="$(get_fingerprints_of_keyring "$ADD_KEYRING")"
      all_add_keys=`$GPG_CMD --keyring $ADD_KEYRING --with-colons --list-keys | grep ^[ps]ub | cut -d: -f5`
      master_keys=`$GPG_CMD --keyring $MASTER --with-colons --list-keys | grep ^pub | cut -d: -f5`
  
              fi
          done
      done
 -    
 +
      for add_key in $add_keys; do
          # export the add keyring one-by-one
 -        rm -f $TMP_KEYRING
 -        $GPG_CMD --keyring $ADD_KEYRING --output $TMP_KEYRING --export $add_key 
 -        # check if signed with the master key and only add in this case
 -        ADDED=0
 +      local TMP_KEYRING="${GPGHOMEDIR}/tmp-keyring.gpg"
 +      $GPG_CMD --batch --yes --keyring "$ADD_KEYRING" --output "$TMP_KEYRING" --export "$add_key"
 +      if ! $GPG_CMD --batch --yes --keyring "$TMP_KEYRING" --import "$MASTER" > "${GPGHOMEDIR}/gpgoutput.log" 2>&1; then
 +          cat "${GPGHOMEDIR}/gpgoutput.log"
 +          false
 +      fi
 +      # check if signed with the master key and only add in this case
 +      ADDED=0
        for master_key in $master_keys; do
 -          if $GPG_CMD --keyring $MASTER --keyring $TMP_KEYRING --check-sigs --with-colons $add_key | grep '^sig:!:' | cut -d: -f5 | grep -q $master_key; then
 -              $GPG --import $TMP_KEYRING
 +          if $GPG_CMD --keyring $TMP_KEYRING --check-sigs --with-colons $add_key | grep '^sig:!:' | cut -d: -f5 | grep -q $master_key; then
 +              $GPG_CMD --batch --yes --keyring "$ADD_KEYRING" --export "$add_key" | $GPG --batch --yes --import
                ADDED=1
            fi
        done
        if [ $ADDED = 0 ]; then
            echo >&2 "Key '$add_key' not added. It is not signed with a master key"
        fi
 +      rm -f "${TMP_KEYRING}"
      done
 -    rm -f $TMP_KEYRING
  }
  
  # update the current archive signing keyring from a network URI
@@@ -106,6 -121,7 +106,6 @@@ net_update() 
        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
      fi
      new_mtime=$(stat -c %Y $keyring)
      if [ $new_mtime -ne $old_mtime ]; then
 -      echo "Checking for new archive signing keys now"
 +      aptkey_echo "Checking for new archive signing keys now"
        add_keys_with_verify_against_master_keyring $keyring $MASTER_KEYRING
      fi
  }
@@@ -137,6 -153,7 +137,6 @@@ update() 
        echo >&2 "Is the &keyring-package; package installed?"
        exit 1
      fi
 -    requires_root
  
      # add new keys from the package;
  
  
      if [ -r "$REMOVED_KEYS" ]; then
        # remove no-longer supported/used keys
 -      keys=`$GPG_CMD --keyring $REMOVED_KEYS --with-colons --list-keys | grep ^pub | cut -d: -f5`
 -      for key in $keys; do
 -          if $GPG --list-keys --with-colons | grep ^pub | cut -d: -f5 | grep -q $key; then
 -              $GPG --quiet --batch --delete-key --yes ${key}
 -          fi
 +      get_fingerprints_of_keyring "$REMOVED_KEYS" | while read key; do
 +          foreach_keyring_do 'remove_key_from_keyring' "$key"
        done
      else
 -      echo "Warning: removed keys keyring  $REMOVED_KEYS missing or not readable" >&2
 +      echo >&2 "Warning: removed keys keyring  $REMOVED_KEYS missing or not readable"
      fi
  }
  
  remove_key_from_keyring() {
 -    local GPG="$GPG_CMD --keyring $1"
 -    # check if the key is in this keyring: the key id is in the 5 column at the end
 -    if ! $GPG --with-colons --list-keys 2>&1 | grep -iq "^pub:[^:]*:[^:]*:[^:]*:[0-9A-F]*$2:"; then
 -      return
 -    fi
 -    if [ ! -w "$1" ]; then
 -      echo >&2 "Key ${2} is in keyring ${1}, but can't be removed as it is read only."
 -      return
 +    local KEYRINGFILE="$1"
 +    shift
 +    # non-existent keyrings have by definition no keys
 +    if [ ! -e "$KEYRINGFILE" ]; then
 +       return
      fi
 -    # check if it is the only key in the keyring and if so remove the keyring altogether
 -    if [ '1' = "$($GPG --with-colons --list-keys | grep "^pub:[^:]*:[^:]*:[^:]*:[0-9A-F]\+:" | wc -l)" ]; then
 -      mv -f "$1" "${1}~" # behave like gpg
 -      return
 -    fi
 -    # we can't just modify pointed to files as these might be in /usr or something
 -    local REALTARGET
 -    if [ -L "$1" ]; then
 -      REALTARGET="$(readlink -f "$1")"
 -      mv -f "$1" "${1}.dpkg-tmp"
 -      cp -a "$REALTARGET" "$1"
 -      ls "$(dirname $1)"
 -    fi
 -    # delete the key from the keyring
 -    $GPG --batch --delete-key --yes "$2"
 -    if [ -n "$REALTARGET" ]; then
 -      # the real backup is the old link, not the copy we made
 -      mv -f "${1}.dpkg-tmp" "${1}~"
 -    fi
 -}
  
 -remove_key() {
 -    requires_root
 +    local GPG="$GPG_CMD --keyring $KEYRINGFILE"
 +    for KEY in "$@"; do
 +      # check if the key is in this keyring: the key id is in the 5 column at the end
-       if ! get_fingerprints_of_keyring "$KEYRINGFILE" | grep -q "^[0-9A-F]*${KEY}$"; then
++      if ! get_fingerprints_of_keyring "$KEYRINGFILE" | grep -iq "^[0-9A-F]*${KEY}$"; then
 +          continue
 +      fi
 +      if [ ! -w "$KEYRINGFILE" ]; then
 +          echo >&2 "Key ${KEY} is in keyring ${KEYRINGFILE}, but can't be removed as it is read only."
 +          continue
 +      fi
 +      # check if it is the only key in the keyring and if so remove the keyring altogether
 +      if [ '1' = "$(get_fingerprints_of_keyring "$KEYRINGFILE" | wc -l)" ]; then
 +          mv -f "$KEYRINGFILE" "${KEYRINGFILE}~" # behave like gpg
 +          return
 +      fi
 +      # we can't just modify pointed to files as these might be in /usr or something
 +      local REALTARGET
 +      if [ -L "$KEYRINGFILE" ]; then
 +          REALTARGET="$(readlink -f "$KEYRINGFILE")"
 +          mv -f "$KEYRINGFILE" "${KEYRINGFILE}.dpkg-tmp"
 +          cp -a "$REALTARGET" "$KEYRINGFILE"
 +      fi
 +      # delete the key from the keyring
 +      $GPG --batch --delete-key --yes "$KEY"
 +      if [ -n "$REALTARGET" ]; then
 +          # the real backup is the old link, not the copy we made
 +          mv -f "${KEYRINGFILE}.dpkg-tmp" "${KEYRINGFILE}~"
 +      fi
 +    done
 +}
  
 -    # if a --keyring was given, just remove from there
 -    if [ -n "$FORCED_KEYRING" ]; then
 -      remove_key_from_keyring "$FORCED_KEYRING" "$1"
 -    else
 +foreach_keyring_do() {
 +   local ACTION="$1"
 +   shift
 +   # if a --keyring was given, just remove from there
 +   if [ -n "$FORCED_KEYRING" ]; then
 +      $ACTION "$FORCED_KEYRING" "$@"
 +   else
        # otherwise all known keyrings are up for inspection
 -      local TRUSTEDFILE="/etc/apt/trusted.gpg"
 -      eval $(apt-config shell TRUSTEDFILE Apt::GPGV::TrustedKeyring)
 -      eval $(apt-config shell TRUSTEDFILE Dir::Etc::Trusted/f)
 -      remove_key_from_keyring "$TRUSTEDFILE" "$1"
 -      TRUSTEDPARTS="/etc/apt/trusted.gpg.d"
 +      if [ -s "$TRUSTEDFILE" ]; then
 +          $ACTION "$TRUSTEDFILE" "$@"
 +      fi
 +      local TRUSTEDPARTS="/etc/apt/trusted.gpg.d"
        eval $(apt-config shell TRUSTEDPARTS Dir::Etc::TrustedParts/d)
        if [ -d "$TRUSTEDPARTS" ]; then
 +          # strip / suffix as gpg will double-slash in that case (#665411)
 +          local STRIPPED_TRUSTEDPARTS="${TRUSTEDPARTS%/}"
 +          if [ "${STRIPPED_TRUSTEDPARTS}/" = "$TRUSTEDPARTS" ]; then
 +              TRUSTEDPARTS="$STRIPPED_TRUSTEDPARTS"
 +          fi
            for trusted in $(run-parts --list "$TRUSTEDPARTS" --regex '^.*\.gpg$'); do
 -              remove_key_from_keyring "$trusted" "$1"
 +              if [ -s "$trusted" ]; then
 +                  $ACTION "$trusted" "$@"
 +              fi
            done
        fi
 +   fi
 +}
 +
 +run_cmd_on_keyring() {
 +    local KEYRINGFILE="$1"
 +    shift
 +    # fingerprint and co will fail if key isn't in this keyring
 +    $GPG_CMD --keyring "$KEYRINGFILE" --batch "$@" 2>/dev/null || true
 +}
 +
 +import_keys_from_keyring() {
 +    local IMPORT="$1"
 +    local KEYRINGFILE="$2"
 +    if ! $GPG_CMD --keyring "$KEYRINGFILE" --batch --import "$IMPORT" > "${GPGHOMEDIR}/gpgoutput.log" 2>&1; then
 +      cat "${GPGHOMEDIR}/gpgoutput.log"
 +      false
 +    fi
 +}
 +
 +merge_keys_into_keyrings() {
 +    local KEYRINGFILE="$1"
 +    local IMPORT="$2"
 +    if ! $GPG_CMD --keyring "$KEYRINGFILE" --batch --import --import-options 'merge-only' "$IMPORT" > "${GPGHOMEDIR}/gpgoutput.log" 2>&1; then
 +      cat "${GPGHOMEDIR}/gpgoutput.log"
 +      false
 +    fi
 +}
 +
 +merge_back_changes() {
 +    if [ -n "$FORCED_KEYRING" ]; then
 +      # if the keyring was forced merge is already done
 +      return
 +    fi
 +    if [ -s "${GPGHOMEDIR}/pubring.gpg" ]; then
 +      # merge all updated keys
 +      foreach_keyring_do 'merge_keys_into_keyrings' "${GPGHOMEDIR}/pubring.gpg"
 +    fi
 +    # look for keys which were added or removed
 +    get_fingerprints_of_keyring "${GPGHOMEDIR}/pubring.orig.gpg" > "${GPGHOMEDIR}/pubring.orig.keylst"
 +    get_fingerprints_of_keyring "${GPGHOMEDIR}/pubring.gpg" > "${GPGHOMEDIR}/pubring.keylst"
 +    sort "${GPGHOMEDIR}/pubring.keylst" "${GPGHOMEDIR}/pubring.orig.keylst" | uniq --unique | while read key; do
 +      if grep -q "^${key}$" "${GPGHOMEDIR}/pubring.orig.keylst"; then
 +          # key isn't part of new keyring, so remove
 +          foreach_keyring_do 'remove_key_from_keyring' "$key"
 +      elif grep -q "^${key}$" "${GPGHOMEDIR}/pubring.keylst"; then
 +          # key is part of new keyring, so we need to import it
 +          create_new_keyring "$TRUSTEDFILE"
 +          if ! $GPG --batch --yes --export "$key" | $GPG_CMD --keyring "$TRUSTEDFILE" --batch --yes --import > "${GPGHOMEDIR}/gpgoutput.log" 2>&1; then
 +             cat "${GPGHOMEDIR}/gpgoutput.log"
 +             false
 +          fi
 +      else
 +          echo >&2 "Errror: Key ${key} (dis)appeared out of nowhere"
 +      fi
 +    done
 +}
 +
 +setup_merged_keyring() {
 +    if [ -z "$FORCED_KEYRING" ]; then
 +      foreach_keyring_do 'import_keys_from_keyring' "${GPGHOMEDIR}/pubring.gpg"
 +      if [ -r "${GPGHOMEDIR}/pubring.gpg" ]; then
 +          cp -a "${GPGHOMEDIR}/pubring.gpg" "${GPGHOMEDIR}/pubring.orig.gpg"
 +      else
 +         touch "${GPGHOMEDIR}/pubring.gpg" "${GPGHOMEDIR}/pubring.orig.gpg"
 +      fi
 +      GPG="$GPG --keyring ${GPGHOMEDIR}/pubring.gpg"
 +    else
 +      GPG="$GPG --keyring $TRUSTEDFILE"
 +      create_new_keyring "$TRUSTEDFILE"
      fi
 -    echo "OK"
  }
  
 +create_new_keyring() {
 +    # gpg defaults to mode 0600 for new keyrings. Create one with 0644 instead.
 +    if ! [ -e "$TRUSTEDFILE" ]; then
 +      if [ -w "$(dirname "$TRUSTEDFILE")" ]; then
 +          touch -- "$TRUSTEDFILE"
 +          chmod 0644 -- "$TRUSTEDFILE"
 +      fi
 +    fi
 +}
  
  usage() {
      echo "Usage: apt-key [--keyring file] [command] [arguments]"
@@@ -327,19 -256,17 +327,19 @@@ while [ -n "$1" ]; d
         shift
         TRUSTEDFILE="$1"
         FORCED_KEYRING="$1"
 -       if [ -r "$TRUSTEDFILE" ] || [ "$2" = 'add' ] || [ "$2" = 'adv' ]; then
 -          GPG="$GPG --keyring $TRUSTEDFILE --primary-keyring $TRUSTEDFILE"
 -       else
 -          echo >&2 "Error: The specified keyring »$TRUSTEDFILE« is missing or not readable"
 -          exit 1
 -       fi
 +       ;;
 +      --secret-keyring)
         shift
 +       FORCED_SECRET_KEYRING="$1"
 +       ;;
 +      --readonly)
 +       merge_back_changes() { true; }
         ;;
        --fakeroot)
         requires_root() { true; }
 -       shift
 +       ;;
 +      --quiet)
 +       aptkey_echo() { true; }
         ;;
        --*)
         echo >&2 "Unknown option: $1"
        *)
         break;;
     esac
 +   shift
  done
  
  if [ -z "$TRUSTEDFILE" ]; then
     TRUSTEDFILE="/etc/apt/trusted.gpg"
     eval $(apt-config shell TRUSTEDFILE Apt::GPGV::TrustedKeyring)
     eval $(apt-config shell TRUSTEDFILE Dir::Etc::Trusted/f)
 -   if [ -r "$TRUSTEDFILE" ]; then
 -      GPG="$GPG --keyring $TRUSTEDFILE"
 -   fi
 -   GPG="$GPG --primary-keyring $TRUSTEDFILE"
 -   TRUSTEDPARTS="/etc/apt/trusted.gpg.d"
 -   eval $(apt-config shell TRUSTEDPARTS Dir::Etc::TrustedParts/d)
 -   if [ -d "$TRUSTEDPARTS" ]; then
 -      # strip / suffix as gpg will double-slash in that case (#665411)
 -      STRIPPED_TRUSTEDPARTS="${TRUSTEDPARTS%/}"
 -      if [ "${STRIPPED_TRUSTEDPARTS}/" = "$TRUSTEDPARTS" ]; then
 -       TRUSTEDPARTS="$STRIPPED_TRUSTEDPARTS"
 -      fi
 -      for trusted in $(run-parts --list "$TRUSTEDPARTS" --regex '^.*\.gpg$'); do
 -       GPG="$GPG --keyring $trusted"
 -      done
 -   fi
  fi
  
  command="$1"
@@@ -364,107 -306,52 +364,107 @@@ if [ -z "$command" ]; the
  fi
  shift
  
 -if [ "$command" != "help" ] && ! which gpg >/dev/null 2>&1; then
 -    echo >&2 "Warning: gnupg does not seem to be installed."
 -    echo >&2 "Warning: apt-key requires gnupg for most operations."
 -    echo >&2
 +if [ "$command" != "help" ]; then
 +    eval $(apt-config shell GPG_EXE Apt::Key::gpgcommand)
 +
 +    if [ -n "$GPG_EXE" ] && which "$GPG_EXE" >/dev/null 2>&1; then
 +      true
 +    elif which gpg >/dev/null 2>&1; then
 +      GPG_EXE="gpg"
 +    elif which gpg2 >/dev/null 2>&1; then
 +      GPG_EXE="gpg2"
 +    else
 +      echo >&2 "Error: gnupg or gnupg2 do not seem to be installed,"
 +      echo >&2 "Error: but apt-key requires gnupg or gnupg2 for operation."
 +      echo >&2
 +      exit 255
 +    fi
 +
 +    GPG_CMD="$GPG_EXE --ignore-time-conflict --no-options --no-default-keyring"
 +
 +    # gpg needs (in different versions more or less) files to function correctly,
 +    # so we give it its own homedir and generate some valid content for it
 +    if [ -n "$TMPDIR" ]; then
 +       # tmpdir is a directory and current user has rwx access to it
 +       # same tests as in apt-pkg/contrib/fileutl.cc GetTempDir()
 +       if [ ! -d "$TMPDIR" ] || [ ! -r "$TMPDIR" ] || [ ! -w "$TMPDIR" ] || [ ! -x "$TMPDIR" ]; then
 +        unset TMPDIR
 +       fi
 +    fi
 +    GPGHOMEDIR="$(mktemp -d)"
 +    CURRENTTRAP="${CURRENTTRAP} rm -rf '${GPGHOMEDIR}';"
 +    trap "${CURRENTTRAP}" 0 HUP INT QUIT ILL ABRT FPE SEGV PIPE TERM
 +    chmod 700 "$GPGHOMEDIR"
 +    # We don't use a secret keyring, of course, but gpg panics and
 +    # implodes if there isn't one available - and writeable for imports
 +    SECRETKEYRING="${GPGHOMEDIR}/secring.gpg"
 +    touch $SECRETKEYRING
 +    GPG_CMD="$GPG_CMD --homedir $GPGHOMEDIR"
 +    # create the trustdb with an (empty) dummy keyring
 +    # older gpgs required it, newer gpgs even warn that it isn't needed,
 +    # but require it nonetheless for some commands, so we just play safe
 +    # here for the foreseeable future and create a dummy one
 +    $GPG_CMD --quiet --check-trustdb --keyring $SECRETKEYRING >/dev/null 2>&1
 +    # tell gpg that it shouldn't try to maintain a trustdb file
 +    GPG_CMD="$GPG_CMD --no-auto-check-trustdb --trust-model always"
 +    GPG="$GPG_CMD"
 +
 +    # for advanced operations, we might really need a secret keyring after all
 +    if [ -n "$FORCED_SECRET_KEYRING" ] && [ -r "$FORCED_SECRET_KEYRING" ]; then
 +      rm -f "$SECRETKEYRING"
 +      cp -a "$FORCED_SECRET_KEYRING" "$SECRETKEYRING"
 +    fi
  fi
  
  case "$command" in
      add)
 -        requires_root
 -        init_keyring "$TRUSTEDFILE"
 -        $GPG --quiet --batch --import "$1"
 -        echo "OK"
 +      requires_root
 +      setup_merged_keyring
 +      $GPG --quiet --batch --import "$@"
 +      merge_back_changes
 +      aptkey_echo "OK"
          ;;
      del|rm|remove)
 -        init_keyring "$TRUSTEDFILE"
 -      remove_key "$1"
 +      requires_root
 +      foreach_keyring_do 'remove_key_from_keyring' "$@"
 +      aptkey_echo "OK"
          ;;
      update)
 -        init_keyring "$TRUSTEDFILE"
 +      requires_root
 +      setup_merged_keyring
        update
 +      merge_back_changes
        ;;
      net-update)
 -        init_keyring "$TRUSTEDFILE"
 +      requires_root
 +      setup_merged_keyring
        net_update
 +      merge_back_changes
        ;;
      list)
 -        init_keyring "$TRUSTEDFILE"
 -        $GPG --batch --list-keys
 -        ;;
 +      foreach_keyring_do 'run_cmd_on_keyring' --list-keys "$@"
 +      ;;
      finger*)
 -        init_keyring "$TRUSTEDFILE"
 -        $GPG --batch --fingerprint
 -        ;;
 -    export)
 -        init_keyring "$TRUSTEDFILE"
 -        $GPG --armor --export "$1"
 -        ;;
 -    exportall)
 -        init_keyring "$TRUSTEDFILE"
 -        $GPG --armor --export
 -        ;;
 +      foreach_keyring_do 'run_cmd_on_keyring' --fingerprint "$@"
 +      ;;
 +    export|exportall)
 +      foreach_keyring_do 'import_keys_from_keyring' "${GPGHOMEDIR}/pubring.gpg"
 +      $GPG_CMD --keyring "${GPGHOMEDIR}/pubring.gpg" --armor --export "$@"
 +      ;;
      adv*)
 -        init_keyring "$TRUSTEDFILE"
 -        echo "Executing: $GPG $*"
 -        $GPG $*
 -        ;;
 +      setup_merged_keyring
 +      aptkey_echo "Executing: $GPG $*"
 +      $GPG "$@"
 +      merge_back_changes
 +      ;;
 +    verify)
 +      setup_merged_keyring
 +      if which gpgv >/dev/null 2>&1; then
 +          gpgv --homedir "${GPGHOMEDIR}" --keyring "${GPGHOMEDIR}/pubring.gpg" --ignore-time-conflict "$@"
 +      else
 +          $GPG --verify "$@"
 +      fi
 +      ;;
      help)
          usage
          ;;
diff --combined configure.ac
index 3fb393335db6d285c6ae75677298d0c78b799065,ebffea4657a8db959390efb70e8d333375fec727..2221833a183ac32791ba7a2dc1e372064f6bb9b1
@@@ -18,7 -18,7 +18,7 @@@ AC_CONFIG_AUX_DIR(buildlib
  AC_CONFIG_HEADER(include/config.h:buildlib/config.h.in include/apti18n.h:buildlib/apti18n.h.in)
  
  PACKAGE="apt"
- PACKAGE_VERSION="1.0.9.7"
+ PACKAGE_VERSION="1.0.9.8"
  PACKAGE_MAIL="APT Development Team <deity@lists.debian.org>"
  AC_DEFINE_UNQUOTED(PACKAGE,"$PACKAGE")
  AC_DEFINE_UNQUOTED(PACKAGE_VERSION,"$PACKAGE_VERSION")
@@@ -91,7 -91,7 +91,7 @@@ AC_CHECK_LIB(curl, curl_easy_init
  
  AC_LANG_PUSH([C++])
  AC_CHECK_HEADER(gtest/gtest.h,,
 -     AC_MSG_ERROR([failed: I need gtest to build tests]),
 +     AC_MSG_WARN([failed: I need gtest (packaged as libgtest-dev) for unit testing]),
  )
  AC_LANG_POP([C++])
  
@@@ -172,12 -172,6 +172,12 @@@ AC_EGREP_HEADER(h_errno, netdb.h, [AC_M
         [AC_MSG_ERROR("not found.")])
     ])
  
 +
 +dnl check for setuid checking function
 +AC_CHECK_FUNCS(getresuid getresgid)
 +AC_SUBST(HAVE_GETRESUID)
 +AC_SUBST(HAVE_GETRESGID)
 +
  dnl Check for doxygen
  AC_PATH_PROG(DOXYGEN, doxygen)
  
diff --combined debian/changelog
index b8954102ef2ab966929fd934c015ae4f22cfafb6,e9634c7633f57c8b3ecf7100dfb35b79633e8b4a..b0d518b17399fe0b0ebdf11d79e057d6f8ffc37c
 +apt (1.1~exp8) experimental; urgency=medium
 +
 +  [ Michael Vogt ]
 +  * merge unstable upload version 1.0.9.3
 +  * Ensure /etc/apt/auth.conf has _apt:root owner
 +  * Use sysconf(_SC_ARG_MAX) to find the size of Dpkg::MaxArgBytes
 +  * Only support Translation-* that are listed in the {In,}Release file
 +  * Call "Dequeue()" for items in AbortTransaction() to fix race
 +  * prepare ABI for feature/socketpair
 +  * Bump ABI to 4.15
 +
 +  [ David Kalnischkies ]
 +  * reenable support for -s (and co) in apt-get source (Closes: 742578)
 +  * run acquire transactions only once
 +  * aborted reverify restores file owner and permission
 +  * test if TMPDIR is accessible before using (Closes: 765951)
 +  * chown finished partial files earlier
 +  * promote filesize to a hashstring
 +
 + -- Michael Vogt <mvo@debian.org>  Thu, 06 Nov 2014 10:01:21 +0100
 +
 +apt (1.1~exp7) experimental; urgency=medium
 +
 +  [ David Kalnischkies ]
 +  * don't cleanup cdrom files in apt-get update (Closes: 765458)
 +  * ignore Acquire::GzipIndexes for cdrom sources
 +
 + -- David Kalnischkies <david@kalnischkies.de>  Wed, 15 Oct 2014 20:12:15 +0200
 +
 +apt (1.1~exp6) experimental; urgency=medium
 +
 +  [ josch ]
 +  * implement the updated build profile spec
 +
 +  [ Michael Vogt ]
 +  * methods/rsh.cc: replace strcat with std::string (Closes: #76442)
 +  * Add new configallowinsecurerepositories to the test framework
 +
 +  [ Guillem Jover ]
 +  * Update Status field values handling
 +
 +  [ David Kalnischkies ]
 +  * don't drop privileges if _apt has not enough rights
 +  * check for available space, excluding root reserved blocks
 +
 + -- Michael Vogt <mvo@debian.org>  Wed, 15 Oct 2014 07:47:36 +0200
 +
 +apt (1.1~exp5) experimental; urgency=medium
 +
 +  [ Michael Vogt ]
 +  * Only rename StatError files in AbortTransaction()
 +  * Document Acquire{MaxReleaseFileSize,AllowInsecureRepositories,
 +    AllowDowngradeToInsecureRepositories} and
 +    --no-allow-insecure-repositories
 +  * Fix backward compatiblity of the new pkgAcquireMethod::DropPrivsOrDie()
 +  * Change default of Acquire::AllowInsecureRepositories to "true"
 +    so that this change is less disruptive, this will be switched
 +    to "false" again after jessie
 +
 +  [ David Kalnischkies ]
 +  * remove useless pdiff filename output (Closes: 764737)
 +  * make --allow-insecure-repositories message an error
 +  * display a warning for unsigned repos
 +  * trusted=yes sources are secure, we just don't know why
 +
 + -- Michael Vogt <mvo@debian.org>  Mon, 13 Oct 2014 16:15:22 +0200
 +
 +apt (1.1~exp4) experimental; urgency=medium
 +
 +  [ Michael Vogt ]
 +  * Merge sid version 1.0.9.2
 +  * feature/acq-trans:
 +    - Make apt-get update more transactional by keeping all data from
 +      a sources.list line in partial/ until all data is good and only
 +      then move it into lists/ in one step
 +    - add new -o Debug::Acquire::Transaction=1 debug option
 +  * feature/expected-size:
 +    Do not download more data in the mehotds than expected if we know
 +    the size. For the InRelease/Release/Release.gpg add new 
 +    Acquire::MaxReleaseFileSize that defaults to 10Mb for now
 +  * Verify the the hashes of the downloaded compressed files early
 +  * Only load unauthenticated data into our parsers when the user
 +    explicitly asked for it via --allow-insecure-repositories
 +    (Acquire::AllowInsecureRepositories)
 +  * Print warning when trying to use unauthenticated repositories
 +  * Use /var/empty as the homedir for _apt
 +  * Revert making pkgAcquire::Item::DescURI() "const" to not break
 +    API
 +  * Do not allow going from a authenticated to unauthenticated repository
 +  * Add missing "adduser" dependency (for the new _apt user)
 +    Thanks to Russ Allbery (Closes: #763004)
 +  * Test if TMPDIR is a directory in apt-key and if not unset it
 +  * add early verification for the .diff/Index download
 +  * Bump library version to libapt-pkg4.14
 +  * Rework pkgAcqMeta{Index,Sig,ClearSig}::{Done,Failed]() for readability
 +  * Ignore EINVAL from prctl(PR_SET_NO_NEW_PRIVS) (closes: 764066)
 +
 +  [ David Kalnischkies ]
 +  * deprecate Pkg->Name in favor of Grp->Name
 +  * drop stored StringItems in favor of in-memory mappings
 +  * de-duplicate version strings in the cache
 +  * fix progress output for (dist-)upgrade calculation
 +  * move PCI::From* methods into CacheSetHelper class (Closes: 686221)
 +  * add a (hidden) --quiet option for apt-key
 +  * only create new trusted.gpg if directory is writeable
 +  * support (multiple) arguments properly in apt-key
 +  * set a primary-keyring only if we have access to it
 +  * merge fragment keyrings in apt-key to avoid hitting gpg limits
 +    (Closes: 733028)
 +  * use apt-key adv (+ gnupg) instead of gpgv for verify
 +  * support gnupg2 as drop-in replacement for gnupg
 +  * allow to specify fingerprints in 'apt-key del'
 +  * use only one --keyring in gpg interactions
 +  * add and use 'apt-key verify' which prefers gpgv over gpg
 +  * remove empty keyrings in trusted.gpg.d on upgrade
 +  * store source name and version in binary cache
 +  * allow fetcher setup without directory creation (Closes: 762898)
 +  * cleanup partial directory of lists in apt-get clean (Closes: #762889)
 +  * allow options between command and -- on commandline
 +  * update symbols file
 +  * support parsing of all hashes for pdiff
 +  * ensure world-readability for trusted.gpg in postinst (Closes: 647001)
 +  * ensure partial dirs are 0700 and owned by _apt:root
 +  * use _apt:root only for partial directories
 +  * display errortext for all Err
 +  * set PR_SET_NO_NEW_PRIVS also if run as non-root
 +
 +  [ James McCoy ]
 +  * ensure apt-key del handles 16-byte key ids (Closes: 754436)
 +
 +  [ Kenshi Muto ]
 +  * Japanese program translation update (Closes: 763033)
 +
 +  [ Trần Ngọc Quân ]
 +  * Set STRIP_FROM_PATH for doxygen
 +
 +  [ Mert Dirik ]
 +  * Turkish program translation update (Closes: 763379)
 +
 +  [ Guillem Jover ]
 +  * apt-get: Create the temporary downloaded changelog inside tmpdir
 +
 +  [ Miroslav Kure ]
 +  * [l10n] Updated Czech translation of apt (Closes: #764055)
 +
 + -- Michael Vogt <mvo@ubuntu.com>  Wed, 08 Oct 2014 09:37:35 +0200
 +
 +apt (1.1~exp3) experimental; urgency=medium
 +
 +  [ Michael Vogt ]
 +  * merged changes from debian/sid up to 1.0.9.1
 +  * Make /var/lib/apt/lists and /var/cache/apt/archives owned
 +    by the new _apt user
 +  * Drop Privileges in the following acquire methods:
 +     copy, http, https, ftp, gpgv, gzip/bzip2/lzma/xz 
 +  * DropPrivs: Improvements based on feedback from error@debian.org
 +
 +  [ Julian Andres Klode ]
 +  * DropPriv: Really call seteuid and not setuid, and add more checks
 +  * Use _apt as our unprivileged user name
 +  * DropPrivs: Also check for saved set-user-ID and set-group-ID
 +  * methods: Fail if we cannot drop privileges
 +  * DropPrivs: Also check for saved set-user-ID and set-group-ID
 +
 + -- Michael Vogt <mvo@debian.org>  Wed, 24 Sep 2014 22:30:09 +0200
 +
 +apt (1.1~exp2) experimental; urgency=medium
 +
 +  [ Guillem Jover ]
 +  * Add new Base256ToNum long long overload function
 +  * Fix ar and tar code to be LFS-safe (Closes: #742882)
 +
 +  [ Michael Vogt ]
 +  * increase libapt-inst to version 1.6
 +  * Only allow "apt-get build-dep path" when path starts with ./ or /
 +  * Allow passing a full path to apt-get install /foo/bar.deb (CLoses: #752327)
 +  * merge changes from the 1.0.6 upload
 +
 + -- Michael Vogt <mvo@debian.org>  Thu, 10 Jul 2014 13:18:08 +0200
 +
 +apt (1.1~exp1) experimental; urgency=low
 +
 +  [ David Kalnischkies ]
 +  * [API Break] change "std::string pkgAcquire::Item::DescURI()" to
 +                       "std::string pkgAcquire::Item::DescURI() const"
 +  * [ABI-Break] increase hashtable size for packages/groups by factor 5
 +  * [ABI-Break] cleanup datatypes mix used in binary cache
 +  * [internal API-Break] remove the Section member from package struct
 +  * use 'best' hash for source authentication (LP: 1098738)
 +  * use HashStringList in the acquire system
 +  * deal with hashes in ftparchive more dynamic as well
 +  * reenable pipelining via hashsum reordering support
 +  * parse and retrieve multiple Descriptions in one record
 +  * improve pkgTagSection scanning and parsing
 +  * invalid cache if architecture set doesn't match (Closes: 745036)
 +
 +  [ Michael Vogt ]
 +  * add support for "apt-get build-dep foo.dsc"
 +  * add support for "apt-get build-dep unpacked-source-dir"
 +  * add support for "apt-get install foo_1.0_all.deb"
 +  * make "apt-get update" progress much more accurate by loading the
 +    sizes of the targets into the fetcher early
 +  * Implement simple by-hash for apt update to improve reliability of
 +    the update. Apt will try to fetch the Packages file via
 +    /by-hash/$hash_type/$hash_value if the repo supports that.
 +    - add APT::Acquire::$(host)::By-Hash=1 knob
 +    - add Acquire-By-Hash=1 to Release file
 +  * add Debug::Acquire::Progress debug option
 +  * [ABI-Break] lp:~mvo/apt/source-hashes:
 +    - use sha{512,256,1} for deb-src when available LP: #1098738
 +  * [ABI-Break] stop exporting the accidently exported parsenetrc() symbol
 +  * [ABI-Break] remove the PACKAGE_MATCHER_ABI_COMPAT defines
 +  * [ABI BREAK] apt-pkg/pkgcache.h:
 +    - adjust pkgCache::State::VerPriority enum, to match reality
 +  * test/integration/test-debsrc-hashes:
 +    - add integration test, thanks to Daniel Hartwig
 +  * [ABI-Break] remove the PACKAGE_MATCHER_ABI_COMPAT defines
 +  * [ABI-Break] Pass struct IndexTarget/indexRecords to
 +    pkgAcqIndex{,Merge}Diffs
 +  * [internal API-Break] rename pkgCache::Package::NextPackage to
 +    pkgCache::Package::Next
 +  * Calculate Percent as part of pkgAcquireStatus to provide a weighted
 +    percent for both items and bytes
 +  * apt-pkg/contrib/macros.h: bump library version to 4.13
 +  * apt-private/acqprogress.cc: do not show file size on IMSHit, it wasn't
 +    fetched
 +  * Fix warnings from clang -Wall/clang -fsanitize=address
 +  * add DropPrivs() and drop privileges to nobody when running the
 +    the buildin apt and dump solvers
 +  * lp:~mvo/apt/webserver-simulate-broken-with-fix346386:
 +    - fix invalid InRelease file download checking and add regression
 +      test to server broken files to the buildin test webserver
 +    - add regression test for LP: #34638
 +
 + -- Michael Vogt <mvo@debian.org>  Thu, 19 Jun 2014 12:01:48 +0200
 +
+ apt (1.0.9.8) unstable; urgency=medium
+   [ David Kalnischkies ]
+   * fix another d(e)select-upgrade typo (LP: #1399037)
+   * properly handle expected filesize in https.
+     Thanks to Robert Edmonds and Anders Kaseorg for initial patchs
+     (Closes: 777565, 781509) (LP: #807303)
+   * avoid depends on std::string implementation for pkgAcquire::Item::Mode
+     (Closes: 781858)
+   * demote VectorizeString gcc attribute from const to pure
+   * keyids in "apt-key del" should be case-insensitive (Closes: 781696)
+   * parse specific-arch dependencies correctly on single-arch systems
+     (Closes: 777760)
+   [ Michael Vogt ]
+   * fix crash in order writing in pkgDPkgPM::WriteApportReport() (LP: #1436626)
+  -- David Kalnischkies <david@kalnischkies.de>  Mon, 13 Apr 2015 07:14:36 +0200
  apt (1.0.9.7) unstable; urgency=medium
  
    [ Tomasz Buchert ]
index 989fe658c428ae963e1838aa2859660883a3a3f7,b4f823ef18d8ff05034cb2073e01b3895fbed617..486acccc80c406c002789135b4119a333fe741aa
@@@ -7,177 -7,113 +7,184 @@@ TESTDIR=$(readlink -f $(dirname $0)
  setupenvironment
  configarchitecture 'amd64'
  
 -msgtest 'Check that paths in list output are not' 'double-slashed'
 -aptkey list 2>&1 | grep -q '//' && msgfail || msgpass
 +# start from a clean plate again
 +cleanplate() {
 +      rm -rf rootdir/etc/apt/trusted.gpg.d/ rootdir/etc/apt/trusted.gpg
 +      mkdir rootdir/etc/apt/trusted.gpg.d/
 +}
  
 -msgtest 'Check that paths in finger output are not' 'double-slashed'
 -aptkey finger 2>&1 | grep -q '//' && msgfail || msgpass
 +testaptkeys() {
 +      if ! aptkey list | grep '^pub' > aptkey.list; then
 +              echo -n > aptkey.list
 +      fi
 +      testfileequal './aptkey.list' "$1"
 +}
  
  echo 'APT::Key::ArchiveKeyring "./keys/joesixpack.pub";
  APT::Key::RemovedKeys "./keys/rexexpired.pub";' > rootdir/etc/apt/apt.conf.d/aptkey.conf
  
 -aptkey list | grep '^pub' > aptkey.list
 -testfileequal ./aptkey.list 'pub   2048R/DBAC8DAE 2010-08-18'
 +testrun() {
 +      cleanplate
 +      ln -sf ${TMPWORKINGDIRECTORY}/keys/joesixpack.pub rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
  
 -testequal 'gpg: key DBAC8DAE: "Joe Sixpack (APT Testcases Dummy) <joe@example.org>" not changed
 +      msgtest 'Check that paths in list output are not' 'double-slashed'
 +      aptkey list 2>&1 | grep -q '//' && msgfail || msgpass
 +
 +      msgtest 'Check that paths in finger output are not' 'double-slashed'
 +      aptkey finger 2>&1 | grep -q '//' && msgfail || msgpass
 +
 +      testaptkeys 'pub   2048R/DBAC8DAE 2010-08-18'
 +
 +      testsuccessequal 'gpg: key DBAC8DAE: "Joe Sixpack (APT Testcases Dummy) <joe@example.org>" not changed
  gpg: Total number processed: 1
  gpg:              unchanged: 1' aptkey --fakeroot update
  
 -aptkey list | grep '^pub' > aptkey.list
 -testfileequal ./aptkey.list 'pub   2048R/DBAC8DAE 2010-08-18'
 +      testaptkeys 'pub   2048R/DBAC8DAE 2010-08-18'
  
 -testsuccess aptkey --fakeroot add ./keys/rexexpired.pub
 +      testfailure test -e rootdir/etc/apt/trusted.gpg
 +      testsuccess aptkey --fakeroot add ./keys/rexexpired.pub
 +      msgtest 'Check if trusted.gpg is created with permissions set to' '0644'
 +      if [ "$(stat -c '%a' rootdir/etc/apt/trusted.gpg )" = '644' ]; then
 +              msgpass
 +      else
 +              msgfail
 +      fi
  
 -aptkey list | grep '^pub' > aptkey.list
 -testfileequal ./aptkey.list 'pub   2048R/27CE74F9 2013-07-12 [expired: 2013-07-13]
 +      testaptkeys 'pub   2048R/27CE74F9 2013-07-12 [expired: 2013-07-13]
  pub   2048R/DBAC8DAE 2010-08-18'
  
 -msgtest 'Execute update again to trigger removal of' 'Rex Expired key'
 -testsuccess --nomsg aptkey --fakeroot update
 -
 -aptkey list | grep '^pub' > aptkey.list
 -testfileequal ./aptkey.list 'pub   2048R/DBAC8DAE 2010-08-18'
 -
 -msgtest "Try to remove a key which exists, but isn't in the" 'forced keyring'
 -testsuccess --nomsg aptkey --fakeroot --keyring rootdir/etc/apt/trusted.gpg del DBAC8DAE
 +      msgtest 'Check that Sixpack key can be' 'exported'
 +      aptkey export 'Sixpack' > aptkey.export
 +      aptkey --keyring rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg exportall > aptkey.exportall
 +      testsuccess --nomsg cmp aptkey.export aptkey.exportall
 +      testsuccess test -s aptkey.export
 +      testsuccess test -s aptkey.exportall
 +
 +      msgtest 'Execute update again to trigger removal of' 'Rex Expired key'
 +      testsuccess --nomsg aptkey --fakeroot update
 +
 +      testaptkeys 'pub   2048R/DBAC8DAE 2010-08-18'
 +
 +      msgtest "Try to remove a key which exists, but isn't in the" 'forced keyring'
 +      testsuccess --nomsg aptkey --fakeroot --keyring rootdir/etc/apt/trusted.gpg del DBAC8DAE
 +
 +      testaptkeys 'pub   2048R/DBAC8DAE 2010-08-18'
 +
 +      testsuccess aptkey --fakeroot del DBAC8DAE
 +      testempty aptkey list
 +
++      msgtest 'Test key removal with' 'lowercase key ID' #keylength somewher between 8byte and short
++      cleanplate
++      cp -a keys/joesixpack.pub rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
++      testsuccess --nomsg aptkey --fakeroot del d141dbac8dae
++      testempty aptkey list
++
 +      msgtest 'Test key removal with' 'single key in real file'
 +      cleanplate
 +      cp -a keys/joesixpack.pub rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
 +      testsuccess --nomsg aptkey --fakeroot del DBAC8DAE
 +      testempty aptkey list
 +      testfailure test -e rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
 +      testsuccess cmp keys/joesixpack.pub rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg~
 +
 +      msgtest 'Test key removal with' 'long key ID'
 +      cleanplate
 +      cp -a keys/joesixpack.pub rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
 +      testsuccess --nomsg aptkey --fakeroot del 5A90D141DBAC8DAE
 +      testempty aptkey list
 +      testfailure test -e rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
 +      testsuccess cmp keys/joesixpack.pub rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg~
 +
 +      msgtest 'Test key removal with' 'fingerprint'
 +      cleanplate
 +      cp -a keys/joesixpack.pub rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
 +      testsuccess --nomsg aptkey --fakeroot del 34A8E9D18DB320F367E8EAA05A90D141DBAC8DAE
 +      testempty aptkey list
 +      testfailure test -e rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
 +      testsuccess cmp keys/joesixpack.pub rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg~
 +
 +      msgtest 'Test key removal with' 'single key in softlink'
 +      cleanplate
 +      ln -s $(readlink -f ./keys/joesixpack.pub) rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
 +      testsuccess --nomsg aptkey --fakeroot del DBAC8DAE
 +      testempty aptkey list
 +      testfailure test -e rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
 +      testsuccess test -L rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg~
 +
 +      cleanplate
 +      testsuccess aptkey --fakeroot add ./keys/joesixpack.pub
 +      testsuccess aptkey --fakeroot add ./keys/marvinparanoid.pub
 +      testaptkeys 'pub   2048R/DBAC8DAE 2010-08-18
 +pub   2048R/528144E2 2011-01-16'
 +      cp -a rootdir/etc/apt/trusted.gpg keys/testcase-multikey.pub # store for reuse
 +
 +      msgtest 'Test key removal with' 'multi key in real file'
 +      cleanplate
 +      cp -a keys/testcase-multikey.pub rootdir/etc/apt/trusted.gpg.d/multikey.gpg
 +      testsuccess --nomsg aptkey --fakeroot del DBAC8DAE
 +      testaptkeys 'pub   2048R/528144E2 2011-01-16'
 +      testsuccess cmp keys/testcase-multikey.pub rootdir/etc/apt/trusted.gpg.d/multikey.gpg~
 +
 +      msgtest 'Test key removal with' 'multi key in softlink'
 +      cleanplate
 +      ln -s $(readlink -f ./keys/testcase-multikey.pub) rootdir/etc/apt/trusted.gpg.d/multikey.gpg
 +      testsuccess --nomsg aptkey --fakeroot del DBAC8DAE
 +      testaptkeys 'pub   2048R/528144E2 2011-01-16'
 +      testsuccess cmp keys/testcase-multikey.pub rootdir/etc/apt/trusted.gpg.d/multikey.gpg~
 +      testfailure test -L rootdir/etc/apt/trusted.gpg.d/multikey.gpg
 +      testsuccess test -L rootdir/etc/apt/trusted.gpg.d/multikey.gpg~
 +
 +      msgtest 'Test key removal with' 'multiple files including key'
 +      cleanplate
 +      cp -a keys/joesixpack.pub rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
 +      cp -a keys/testcase-multikey.pub rootdir/etc/apt/trusted.gpg.d/multikey.gpg
 +      testsuccess --nomsg aptkey --fakeroot del DBAC8DAE
 +      testaptkeys 'pub   2048R/528144E2 2011-01-16'
 +      testfailure test -e rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
 +      testsuccess cmp keys/joesixpack.pub rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg~
 +      testsuccess cmp keys/testcase-multikey.pub rootdir/etc/apt/trusted.gpg.d/multikey.gpg~
 +
 +      cleanplate
 +      cp -a keys/joesixpack.pub rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
 +      cp -a keys/testcase-multikey.pub rootdir/etc/apt/trusted.gpg.d/multikey.gpg
 +      testaptkeys 'pub   2048R/DBAC8DAE 2010-08-18
 +pub   2048R/DBAC8DAE 2010-08-18
 +pub   2048R/528144E2 2011-01-16'
 +      msgtest 'Test merge-back of' 'added keys'
 +      testsuccess --nomsg aptkey adv --batch --yes --import keys/rexexpired.pub
 +      testaptkeys 'pub   2048R/27CE74F9 2013-07-12 [expired: 2013-07-13]
 +pub   2048R/DBAC8DAE 2010-08-18
 +pub   2048R/DBAC8DAE 2010-08-18
 +pub   2048R/528144E2 2011-01-16'
  
 -aptkey list | grep '^pub' > aptkey.list
 -testfileequal ./aptkey.list 'pub   2048R/DBAC8DAE 2010-08-18'
 +      msgtest 'Test merge-back of' 'removed keys'
 +      testsuccess --nomsg aptkey adv --batch --yes --delete-keys 27CE74F9
 +      testaptkeys 'pub   2048R/DBAC8DAE 2010-08-18
 +pub   2048R/DBAC8DAE 2010-08-18
 +pub   2048R/528144E2 2011-01-16'
  
 -testsuccess aptkey --fakeroot del DBAC8DAE
 -testempty aptkey list
 +      msgtest 'Test merge-back of' 'removed duplicate keys'
 +      testsuccess --nomsg aptkey adv --batch --yes --delete-keys DBAC8DAE
 +      testaptkeys 'pub   2048R/528144E2 2011-01-16'
 +}
  
 -# start from a clean plate again
 -cleanplate() {
 -      rm -rf rootdir/etc/apt/trusted.gpg.d/ rootdir/etc/apt/trusted.gpg
 -      mkdir rootdir/etc/apt/trusted.gpg.d/
 +setupgpgcommand() {
 +      echo "APT::Key::GPGCommand \"$1\";" > rootdir/etc/apt/apt.conf.d/00gpgcmd
 +      msgtest 'Test that apt-key uses for the following tests command' "$1"
 +      aptkey adv --version >aptkey.version 2>&1
 +      if grep -q "^Executing: $1 --" aptkey.version; then
 +              msgpass
 +      else
 +              cat aptkey.version
 +              msgfail
 +      fi
  }
  
 -msgtest 'Test key removal with' 'single key in real file'
 -cleanplate
 -cp -a keys/joesixpack.pub rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
 -testsuccess --nomsg aptkey --fakeroot del DBAC8DAE
 -testempty aptkey list
 -testsuccess test ! -e rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
 -testsuccess cmp keys/joesixpack.pub rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg~
 -
 -msgtest 'Test key removal with' 'single key in softlink'
 -cleanplate
 -ln -s $(readlink -f ./keys/joesixpack.pub) rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
 -testsuccess --nomsg aptkey --fakeroot del DBAC8DAE
 -testempty aptkey list
 -testsuccess test ! -e rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
 -testsuccess test -L rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg~
 -
 -cleanplate
 -testsuccess aptkey --fakeroot add ./keys/joesixpack.pub
 -testsuccess aptkey --fakeroot add ./keys/marvinparanoid.pub
 -aptkey list | grep '^pub' > aptkey.list
 -testfileequal ./aptkey.list 'pub   2048R/DBAC8DAE 2010-08-18
 -pub   2048R/528144E2 2011-01-16'
 -cp -a rootdir/etc/apt/trusted.gpg keys/testcase-multikey.pub # store for reuse
 -
 -msgtest 'Test key removal with' 'multi key in real file'
 -cleanplate
 -cp -a keys/testcase-multikey.pub rootdir/etc/apt/trusted.gpg.d/multikey.gpg
 -testsuccess --nomsg aptkey --fakeroot del DBAC8DAE
 -aptkey list | grep '^pub' > aptkey.list
 -testfileequal ./aptkey.list 'pub   2048R/528144E2 2011-01-16'
 -testsuccess cmp keys/testcase-multikey.pub rootdir/etc/apt/trusted.gpg.d/multikey.gpg~
 -
 -msgtest 'Test key removal with' 'multi key in softlink'
 -cleanplate
 -ln -s $(readlink -f ./keys/testcase-multikey.pub) rootdir/etc/apt/trusted.gpg.d/multikey.gpg
 -testsuccess --nomsg aptkey --fakeroot del DBAC8DAE
 -aptkey list | grep '^pub' > aptkey.list
 -testfileequal ./aptkey.list 'pub   2048R/528144E2 2011-01-16'
 -testsuccess cmp keys/testcase-multikey.pub rootdir/etc/apt/trusted.gpg.d/multikey.gpg~
 -testsuccess test ! -L rootdir/etc/apt/trusted.gpg.d/multikey.gpg
 -testsuccess test -L rootdir/etc/apt/trusted.gpg.d/multikey.gpg~
 -
 -msgtest 'Test key removal with' 'multiple files including key'
 -cleanplate
 -cp -a keys/joesixpack.pub rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
 -cp -a keys/testcase-multikey.pub rootdir/etc/apt/trusted.gpg.d/multikey.gpg
 -testsuccess --nomsg aptkey --fakeroot del DBAC8DAE
 -aptkey list | grep '^pub' > aptkey.list
 -testfileequal ./aptkey.list 'pub   2048R/528144E2 2011-01-16'
 -testsuccess test ! -e rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
 -testsuccess cmp keys/joesixpack.pub rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg~
 -testsuccess cmp keys/testcase-multikey.pub rootdir/etc/apt/trusted.gpg.d/multikey.gpg~
 -
 -msgtest 'Test key removal with' '8 byte key ID'
 -cleanplate
 -cp -a keys/joesixpack.pub rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
 -testsuccess --nomsg aptkey --fakeroot del 5A90D141DBAC8DAE
 -testempty aptkey list
 -
 -msgtest 'Test key removal with' 'lowercase key ID' #keylength somewher between 8byte and short
 -cleanplate
 -cp -a keys/joesixpack.pub rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
 -testsuccess --nomsg aptkey --fakeroot del d141dbac8dae
 -testempty aptkey list
 +# run with default (whatever this is)
 +testrun
 +# run with …
 +setupgpgcommand 'gpg'
 +testrun
 +setupgpgcommand 'gpg2'
 +testrun
++
index 490abb8731bab378d518fe9626c93e15d1ca3cd9,240f1a4d1efa2c542264121d9534cc324df06291..7870126f51ea012ee163d2bb429f8753380fc25a
@@@ -7,15 -7,19 +7,19 @@@ setupenvironmen
  configarchitecture 'amd64' 'i386' 'armel'
  
  insertpackage 'unstable' 'cool-foo' 'amd64,i386' '1.0' 'Depends: foo'
+ insertpackage 'unstable' 'cool-foo-x64' 'amd64' '1.0' 'Depends: foo:amd64'
+ insertpackage 'unstable' 'cool-foo-x32' 'amd64' '1.0' 'Depends: foo:i386'
  insertpackage 'unstable' 'foo' 'amd64,i386,armel' '1.0' 'Multi-Arch: foreign'
  
  insertpackage 'unstable' 'cool-bar' 'amd64,i386' '1.0' 'Depends: bar-provider'
+ insertpackage 'unstable' 'cool-bar-x64' 'amd64' '1.0' 'Depends: bar-provider:amd64'
+ insertpackage 'unstable' 'cool-bar-x32' 'amd64' '1.0' 'Depends: bar-provider:i386'
  insertpackage 'unstable' 'bar' 'amd64,i386,armel' '1.0' 'Provides: bar-provider
  Multi-Arch: foreign'
  
  setupaptarchive
  
 -testequal 'Reading package lists...
 +testsuccessequal 'Reading package lists...
  Building dependency tree...
  The following extra packages will be installed:
    foo
@@@ -27,29 -31,7 +31,7 @@@ Inst cool-foo:i386 (1.0 unstable [i386]
  Conf foo (1.0 unstable [amd64])
  Conf cool-foo:i386 (1.0 unstable [i386])' aptget install cool-foo:i386 -s
  
- testsuccessequal 'Reading package lists...
- Building dependency tree...
- The following extra packages will be installed:
-   foo
- The following NEW packages will be installed:
-   cool-foo foo
- 0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
- Inst foo (1.0 unstable [amd64])
- Inst cool-foo (1.0 unstable [amd64])
- Conf foo (1.0 unstable [amd64])
- Conf cool-foo (1.0 unstable [amd64])' aptget install cool-foo:amd64 -s
- testsuccessequal 'Reading package lists...
- Building dependency tree...
- The following NEW packages will be installed:
-   cool-foo foo
- 0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
- Inst foo (1.0 unstable [amd64])
- Inst cool-foo (1.0 unstable [amd64])
- Conf foo (1.0 unstable [amd64])
- Conf cool-foo (1.0 unstable [amd64])' aptget install cool-foo:amd64 foo:amd64 -s
 -testequal 'Reading package lists...
 +testsuccessequal 'Reading package lists...
  Building dependency tree...
  The following NEW packages will be installed:
    cool-foo foo:i386
@@@ -59,7 -41,7 +41,7 @@@ Inst cool-foo (1.0 unstable [amd64]
  Conf foo:i386 (1.0 unstable [i386])
  Conf cool-foo (1.0 unstable [amd64])' aptget install cool-foo:amd64 foo:i386 -s
  
 -testequal 'Reading package lists...
 +testsuccessequal 'Reading package lists...
  Building dependency tree...
  The following NEW packages will be installed:
    cool-foo foo:armel
@@@ -69,11 -51,7 +51,7 @@@ Inst cool-foo (1.0 unstable [amd64]
  Conf foo:armel (1.0 unstable [armel])
  Conf cool-foo (1.0 unstable [amd64])' aptget install cool-foo:amd64 foo:armel -s
  
 -testequal 'Reading package lists...
 +testsuccessequal 'Reading package lists...
  Building dependency tree...
  The following extra packages will be installed:
    bar
@@@ -85,8 -63,62 +63,62 @@@ Inst cool-bar:i386 (1.0 unstable [i386]
  Conf bar (1.0 unstable [amd64])
  Conf cool-bar:i386 (1.0 unstable [i386])' aptget install cool-bar:i386 -s
  
 -testequal 'Reading package lists...
 +testsuccessequal 'Reading package lists...
  Building dependency tree...
 -testequal 'Reading package lists...
+ The following NEW packages will be installed:
+   bar:i386 cool-bar
+ 0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+ Inst bar:i386 (1.0 unstable [i386])
+ Inst cool-bar (1.0 unstable [amd64])
+ Conf bar:i386 (1.0 unstable [i386])
+ Conf cool-bar (1.0 unstable [amd64])' aptget install cool-bar:amd64 bar:i386 -s
 -testequal "Reading package lists...
++testsuccessequal 'Reading package lists...
+ Building dependency tree...
+ The following NEW packages will be installed:
+   bar:armel cool-bar
+ 0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+ Inst bar:armel (1.0 unstable [armel])
+ Inst cool-bar (1.0 unstable [amd64])
+ Conf bar:armel (1.0 unstable [armel])
+ Conf cool-bar (1.0 unstable [amd64])' aptget install cool-bar:amd64 bar:armel -s
 -      testequal 'Reading package lists...
++testsuccessequal "Reading package lists...
+ Building dependency tree...
+ Note, selecting 'bar:i386' instead of 'bar-provider:i386'
+ The following NEW packages will be installed:
+   bar:i386 cool-bar
+ 0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+ Inst bar:i386 (1.0 unstable [i386])
+ Inst cool-bar (1.0 unstable [amd64])
+ Conf bar:i386 (1.0 unstable [i386])
+ Conf cool-bar (1.0 unstable [amd64])" aptget install cool-bar bar-provider:i386 -s -q=0
+ satisfiable_in_singlearch() {
 -      testequal 'Reading package lists...
++      testsuccessequal 'Reading package lists...
+ Building dependency tree...
+ The following extra packages will be installed:
+   foo
+ The following NEW packages will be installed:
+   cool-foo foo
+ 0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+ Inst foo (1.0 unstable [amd64])
+ Inst cool-foo (1.0 unstable [amd64])
+ Conf foo (1.0 unstable [amd64])
+ Conf cool-foo (1.0 unstable [amd64])' aptget install cool-foo:amd64 -s
 -      testequal 'Reading package lists...
++      testsuccessequal 'Reading package lists...
+ Building dependency tree...
+ The following NEW packages will be installed:
+   cool-foo foo
+ 0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+ Inst foo (1.0 unstable [amd64])
+ Inst cool-foo (1.0 unstable [amd64])
+ Conf foo (1.0 unstable [amd64])
+ Conf cool-foo (1.0 unstable [amd64])' aptget install cool-foo:amd64 foo:amd64 -s
++      testsuccessequal 'Reading package lists...
+ Building dependency tree...
  The following extra packages will be installed:
    bar
  The following NEW packages will be installed:
@@@ -97,7 -129,7 +129,7 @@@ Inst cool-bar (1.0 unstable [amd64]
  Conf bar (1.0 unstable [amd64])
  Conf cool-bar (1.0 unstable [amd64])' aptget install cool-bar:amd64 -s
  
- testsuccessequal 'Reading package lists...
 -      testequal 'Reading package lists...
++      testsuccessequal 'Reading package lists...
  Building dependency tree...
  The following NEW packages will be installed:
    bar cool-bar
@@@ -107,44 -139,71 +139,71 @@@ Inst cool-bar (1.0 unstable [amd64]
  Conf bar (1.0 unstable [amd64])
  Conf cool-bar (1.0 unstable [amd64])' aptget install cool-bar:amd64 bar:amd64 -s
  
- testsuccessequal 'Reading package lists...
 -      testequal "Reading package lists...
++      testsuccessequal "Reading package lists...
  Building dependency tree...
+ Note, selecting 'bar' instead of 'bar-provider'
  The following NEW packages will be installed:
-   bar:i386 cool-bar
+   bar cool-bar
  0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
- Inst bar:i386 (1.0 unstable [i386])
+ Inst bar (1.0 unstable [amd64])
  Inst cool-bar (1.0 unstable [amd64])
- Conf bar:i386 (1.0 unstable [i386])
- Conf cool-bar (1.0 unstable [amd64])' aptget install cool-bar:amd64 bar:i386 -s
+ Conf bar (1.0 unstable [amd64])
+ Conf cool-bar (1.0 unstable [amd64])" aptget install cool-bar bar-provider -s -q=0
  
- testsuccessequal 'Reading package lists...
 -      testequal 'Reading package lists...
++      testsuccessequal 'Reading package lists...
  Building dependency tree...
+ The following extra packages will be installed:
+   foo
  The following NEW packages will be installed:
-   bar:armel cool-bar
+   cool-foo-x64 foo
  0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
- Inst bar:armel (1.0 unstable [armel])
- Inst cool-bar (1.0 unstable [amd64])
- Conf bar:armel (1.0 unstable [armel])
- Conf cool-bar (1.0 unstable [amd64])' aptget install cool-bar:amd64 bar:armel -s
+ Inst foo (1.0 unstable [amd64])
+ Inst cool-foo-x64 (1.0 unstable [amd64])
+ Conf foo (1.0 unstable [amd64])
+ Conf cool-foo-x64 (1.0 unstable [amd64])' aptget install cool-foo-x64 -s
+ }
  
- testsuccessequal "Reading package lists...
+ #FIXME: do not work in single-arch as i386 isn't known at cache generation time
 -      testequal 'Reading package lists...
++      testsuccessequal 'Reading package lists...
  Building dependency tree...
- Note, selecting 'bar' instead of 'bar-provider'
+ The following extra packages will be installed:
+   foo
  The following NEW packages will be installed:
-   bar cool-bar
+   cool-foo-x32 foo
+ 0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+ Inst foo (1.0 unstable [amd64])
+ Inst cool-foo-x32 (1.0 unstable [amd64])
+ Conf foo (1.0 unstable [amd64])
+ Conf cool-foo-x32 (1.0 unstable [amd64])' aptget install cool-foo-x32 -s
 -      testequal 'Reading package lists...
++      testsuccessequal 'Reading package lists...
+ Building dependency tree...
+ The following extra packages will be installed:
+   bar
+ The following NEW packages will be installed:
+   bar cool-bar-x32
  0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
  Inst bar (1.0 unstable [amd64])
- Inst cool-bar (1.0 unstable [amd64])
+ Inst cool-bar-x32 (1.0 unstable [amd64])
  Conf bar (1.0 unstable [amd64])
- Conf cool-bar (1.0 unstable [amd64])" aptget install cool-bar bar-provider -s -q=0
+ Conf cool-bar-x32 (1.0 unstable [amd64])' aptget install cool-bar-x32 -s -q=0
  
- testsuccessequal "Reading package lists...
 -      testequal 'Reading package lists...
++      testsuccessequal 'Reading package lists...
  Building dependency tree...
- Note, selecting 'bar:i386' instead of 'bar-provider:i386'
+ The following extra packages will be installed:
+   bar
  The following NEW packages will be installed:
-   bar:i386 cool-bar
+   bar cool-bar-x64
  0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
- Inst bar:i386 (1.0 unstable [i386])
- Inst cool-bar (1.0 unstable [amd64])
- Conf bar:i386 (1.0 unstable [i386])
- Conf cool-bar (1.0 unstable [amd64])" aptget install cool-bar bar-provider:i386 -s -q=0
+ Inst bar (1.0 unstable [amd64])
+ Inst cool-bar-x64 (1.0 unstable [amd64])
+ Conf bar (1.0 unstable [amd64])
+ Conf cool-bar-x64 (1.0 unstable [amd64])' aptget install cool-bar-x64 -s -q=0
+ satisfiable_in_singlearch
+ msgmsg 'switch to single architecture'
+ configarchitecture 'amd64'
+ satisfiable_in_singlearch
index cb6bc3cc24cd94d2891085f597308c2180eafe6f,ccfced15095e3c7ec75bfbe3fdc184fbf4df6c49..1c72d7b229d93fec7f678ff7dd0512d3b0695ff1
@@@ -12,16 -12,19 +12,19 @@@ insertinstalledpackage 'provider' 'amd6
  
  insertpackage 'unstable' 'pre-depender' 'all' '1' 'Pre-Depends: libc6:i386'
  insertpackage 'unstable' 'depender' 'all' '1' 'Depends: libc6:i386'
+ insertpackage 'unstable' 'depender-x32' 'i386,amd64' '1' 'Depends: libc6:i386'
+ insertpackage 'unstable' 'depender-x64' 'i386,amd64' '1' 'Depends: libc6:amd64'
  
  insertpackage 'unstable' 'breaker' 'all' '1' 'Breaks: libold (<< 2)'
- insertpackage 'unstable' 'breaker-x32' 'amd64' '1' 'Breaks: libold:i386 (<< 2)'
- insertpackage 'unstable' 'breaker-x64' 'i386' '1' 'Breaks: libold:amd64 (<< 2)'
+ insertpackage 'unstable' 'breaker-x32' 'i386,amd64' '1' 'Breaks: libold:i386 (<< 2)'
+ insertpackage 'unstable' 'breaker-x64' 'i386,amd64' '1' 'Breaks: libold:amd64 (<< 2)'
  # conflicts with no effect
  insertpackage 'unstable' 'oldconflictor' 'all' '1' 'Conflicts: libold (<< 0)'
  insertpackage 'unstable' 'oldconflictor-x32' 'amd64' '1' 'Conflicts: libold:i386 (<< 0)'
  insertpackage 'unstable' 'oldconflictor-x64' 'i386' '1' 'Conflicts: libold:amd64 (<< 0)'
  
  insertpackage 'unstable' 'foo-depender' 'i386,amd64' '1' 'Depends: foo'
+ insertpackage 'unstable' 'foo-native-depender' 'amd64' '1' 'Depends: foo:amd64'
  insertpackage 'unstable' 'foo-foreign-depender' 'i386' '1' 'Depends: foo:amd64'
  
  insertpackage 'unstable' 'foo-conflictor' 'i386,amd64' '1' 'Conflicts: foo'
@@@ -30,7 -33,7 +33,7 @@@ insertpackage 'unstable' 'foo-no-confli
  
  setupaptarchive
  
 -testequal 'Reading package lists...
 +testsuccessequal 'Reading package lists...
  Building dependency tree...
  The following extra packages will be installed:
    libc6:i386
@@@ -42,7 -45,7 +45,7 @@@ Conf libc6:i386 (1 unstable [i386]
  Inst pre-depender (1 unstable [all])
  Conf pre-depender (1 unstable [all])' aptget install pre-depender -s
  
 -testequal 'Reading package lists...
 +testsuccessequal 'Reading package lists...
  Building dependency tree...
  The following extra packages will be installed:
    libc6:i386
@@@ -54,8 -57,56 +57,56 @@@ Inst depender (1 unstable [all]
  Conf libc6:i386 (1 unstable [i386])
  Conf depender (1 unstable [all])' aptget install depender -s
  
 -testequal 'Reading package lists...
 +testsuccessequal 'Reading package lists...
  Building dependency tree...
+ The following extra packages will be installed:
+   libc6:i386
+ The following NEW packages will be installed:
+   depender-x32:i386 libc6:i386
+ 0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+ Inst libc6:i386 (1 unstable [i386])
+ Inst depender-x32:i386 (1 unstable [i386])
+ Conf libc6:i386 (1 unstable [i386])
+ Conf depender-x32:i386 (1 unstable [i386])' aptget install depender-x32:i386 -s
+ testequal 'Reading package lists...
+ Building dependency tree...
+ The following extra packages will be installed:
+   libc6:i386
+ The following NEW packages will be installed:
+   depender-x32 libc6:i386
+ 0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+ Inst libc6:i386 (1 unstable [i386])
+ Inst depender-x32 (1 unstable [amd64])
+ Conf libc6:i386 (1 unstable [i386])
+ Conf depender-x32 (1 unstable [amd64])' aptget install depender-x32:amd64 -s
+ testequal 'Reading package lists...
+ Building dependency tree...
+ The following extra packages will be installed:
+   libc6
+ The following NEW packages will be installed:
+   depender-x64 libc6
+ 0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+ Inst libc6 (1 unstable [amd64])
+ Inst depender-x64 (1 unstable [amd64])
+ Conf libc6 (1 unstable [amd64])
+ Conf depender-x64 (1 unstable [amd64])' aptget install depender-x64:amd64 -s
+ testequal 'Reading package lists...
+ Building dependency tree...
+ The following extra packages will be installed:
+   libc6
+ The following NEW packages will be installed:
+   depender-x64:i386 libc6
+ 0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+ Inst libc6 (1 unstable [amd64])
+ Inst depender-x64:i386 (1 unstable [i386])
+ Conf libc6 (1 unstable [amd64])
+ Conf depender-x64:i386 (1 unstable [i386])' aptget install depender-x64:i386 -s
+ testequal 'Reading package lists...
+ Building dependency tree...
  The following packages will be REMOVED:
    libold libold:i386
  The following NEW packages will be installed:
@@@ -66,7 -117,7 +117,7 @@@ Remv libold:i386 [1
  Inst breaker (1 unstable [all])
  Conf breaker (1 unstable [all])' aptget install breaker -s
  
 -testequal 'Reading package lists...
 +testsuccessequal 'Reading package lists...
  Building dependency tree...
  The following packages will be REMOVED:
    libold:i386
@@@ -75,9 -126,31 +126,31 @@@ The following NEW packages will be inst
  0 upgraded, 1 newly installed, 1 to remove and 0 not upgraded.
  Remv libold:i386 [1]
  Inst breaker-x32 (1 unstable [amd64])
- Conf breaker-x32 (1 unstable [amd64])' aptget install breaker-x32 -s
+ Conf breaker-x32 (1 unstable [amd64])' aptget install breaker-x32:amd64 -s
+ testequal 'Reading package lists...
+ Building dependency tree...
+ The following packages will be REMOVED:
+   libold:i386
+ The following NEW packages will be installed:
+   breaker-x32:i386
+ 0 upgraded, 1 newly installed, 1 to remove and 0 not upgraded.
+ Remv libold:i386 [1]
+ Inst breaker-x32:i386 (1 unstable [i386])
+ Conf breaker-x32:i386 (1 unstable [i386])' aptget install breaker-x32:i386 -s
+ testequal 'Reading package lists...
+ Building dependency tree...
+ The following packages will be REMOVED:
+   libold
+ The following NEW packages will be installed:
+   breaker-x64
+ 0 upgraded, 1 newly installed, 1 to remove and 0 not upgraded.
+ Remv libold [1]
+ Inst breaker-x64 (1 unstable [amd64])
+ Conf breaker-x64 (1 unstable [amd64])' aptget install breaker-x64:amd64 -s
  
 -testequal 'Reading package lists...
 +testsuccessequal 'Reading package lists...
  Building dependency tree...
  The following packages will be REMOVED:
    libold
@@@ -86,9 -159,9 +159,9 @@@ The following NEW packages will be inst
  0 upgraded, 1 newly installed, 1 to remove and 0 not upgraded.
  Remv libold [1]
  Inst breaker-x64:i386 (1 unstable [i386])
- Conf breaker-x64:i386 (1 unstable [i386])' aptget install breaker-x64 -s
+ Conf breaker-x64:i386 (1 unstable [i386])' aptget install breaker-x64:i386 -s
  
 -testequal 'Reading package lists...
 +testsuccessequal 'Reading package lists...
  Building dependency tree...
  The following NEW packages will be installed:
    oldconflictor
  Inst oldconflictor (1 unstable [all])
  Conf oldconflictor (1 unstable [all])' aptget install oldconflictor -s
  
 -testequal 'Reading package lists...
 +testsuccessequal 'Reading package lists...
  Building dependency tree...
  The following NEW packages will be installed:
    oldconflictor-x32
  Inst oldconflictor-x32 (1 unstable [amd64])
  Conf oldconflictor-x32 (1 unstable [amd64])' aptget install oldconflictor-x32 -s
  
 -testequal 'Reading package lists...
 +testsuccessequal 'Reading package lists...
  Building dependency tree...
  The following NEW packages will be installed:
    oldconflictor-x64:i386
  Inst oldconflictor-x64:i386 (1 unstable [i386])
  Conf oldconflictor-x64:i386 (1 unstable [i386])' aptget install oldconflictor-x64 -s
  
 -testequal 'Reading package lists...
 +testsuccessequal 'Reading package lists...
  Building dependency tree...
  The following NEW packages will be installed:
    foo-depender
  Inst foo-depender (1 unstable [amd64])
  Conf foo-depender (1 unstable [amd64])' aptget install foo-depender -s
  
 -testequal 'Reading package lists...
 +testfailureequal 'Reading package lists...
  Building dependency tree...
  Some packages could not be installed. This may mean that you have
  requested an impossible situation or if you are using the unstable
@@@ -132,15 -205,23 +205,23 @@@ The following packages have unmet depen
   foo-depender:i386 : Depends: foo:i386 but it is not installable
  E: Unable to correct problems, you have held broken packages.' aptget install foo-depender:i386 -s
  
 -testequal 'Reading package lists...
 +testsuccessequal 'Reading package lists...
  Building dependency tree...
+ The following NEW packages will be installed:
+   foo-native-depender
+ 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
+ Inst foo-native-depender (1 unstable [amd64])
+ Conf foo-native-depender (1 unstable [amd64])' aptget install foo-native-depender -s
+ testequal 'Reading package lists...
+ Building dependency tree...
  The following NEW packages will be installed:
    foo-foreign-depender:i386
  0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
  Inst foo-foreign-depender:i386 (1 unstable [i386])
  Conf foo-foreign-depender:i386 (1 unstable [i386])' aptget install foo-foreign-depender:i386 -s
  
 -testequal 'Reading package lists...
 +testsuccessequal 'Reading package lists...
  Building dependency tree...
  The following packages will be REMOVED:
    provider
@@@ -151,7 -232,7 +232,7 @@@ Remv provider [1
  Inst foo-conflictor (1 unstable [amd64])
  Conf foo-conflictor (1 unstable [amd64])' aptget install foo-conflictor -s
  
 -testequal 'Reading package lists...
 +testsuccessequal 'Reading package lists...
  Building dependency tree...
  The following packages will be REMOVED:
    provider
@@@ -162,7 -243,7 +243,7 @@@ Remv provider [1
  Inst foo-conflictor:i386 (1 unstable [i386])
  Conf foo-conflictor:i386 (1 unstable [i386])' aptget install foo-conflictor:i386 -s
  
 -testequal 'Reading package lists...
 +testsuccessequal 'Reading package lists...
  Building dependency tree...
  The following packages will be REMOVED:
    provider
@@@ -173,10 -254,69 +254,69 @@@ Remv provider [1
  Inst foo-foreign-conflictor:i386 (1 unstable [i386])
  Conf foo-foreign-conflictor:i386 (1 unstable [i386])' aptget install foo-foreign-conflictor:i386 -s
  
 -testequal 'Reading package lists...
 +testsuccessequal 'Reading package lists...
  Building dependency tree...
  The following NEW packages will be installed:
    foo-no-conflictor:i386
  0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
  Inst foo-no-conflictor:i386 (1 unstable [i386])
  Conf foo-no-conflictor:i386 (1 unstable [i386])' aptget install foo-no-conflictor:i386 -s
+ msgmsg 'switch to single architecture'
+ configarchitecture 'amd64'
+ testequal 'Reading package lists...
+ Building dependency tree...
+ The following extra packages will be installed:
+   libc6
+ The following NEW packages will be installed:
+   depender-x64 libc6
+ 0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
+ Inst libc6 (1 unstable [amd64])
+ Inst depender-x64 (1 unstable [amd64])
+ Conf libc6 (1 unstable [amd64])
+ Conf depender-x64 (1 unstable [amd64])' aptget install depender-x64 -s
+ testequal 'Reading package lists...
+ Building dependency tree...
+ E: Unable to locate package depender-x64' aptget install depender-x64:i386 -s
+ testequal 'Reading package lists...
+ Building dependency tree...
+ The following NEW packages will be installed:
+   foo-native-depender
+ 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
+ Inst foo-native-depender (1 unstable [amd64])
+ Conf foo-native-depender (1 unstable [amd64])' aptget install foo-native-depender -s
+ # libold:i386 is installed, but we don't see it as i386 isn't configured
+ testequal 'Reading package lists...
+ Building dependency tree...
+ The following NEW packages will be installed:
+   breaker-x32
+ 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
+ Inst breaker-x32 (1 unstable [amd64])
+ Conf breaker-x32 (1 unstable [amd64])' aptget install breaker-x32:amd64 -s
+ testequal 'Reading package lists...
+ Building dependency tree...
+ The following packages will be REMOVED:
+   libold
+ The following NEW packages will be installed:
+   breaker-x64
+ 0 upgraded, 1 newly installed, 1 to remove and 0 not upgraded.
+ Remv libold [1]
+ Inst breaker-x64 (1 unstable [amd64])
+ Conf breaker-x64 (1 unstable [amd64])' aptget install breaker-x64:amd64 -s
+ testequal 'Reading package lists...
+ Building dependency tree...
+ Some packages could not be installed. This may mean that you have
+ requested an impossible situation or if you are using the unstable
+ distribution that some required packages have not yet been created
+ or been moved out of Incoming.
+ The following information may help to resolve the situation:
+ The following packages have unmet dependencies:
+  depender-x32 : Depends: libc6:i386 but it is not installable
+ E: Unable to correct problems, you have held broken packages.' aptget install depender-x32 -s