Michael Vogt пре 15 година
родитељ
комит
70d761713b

+ 0 - 24
apt-pkg/acquire-item.cc

@@ -17,7 +17,6 @@
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/sourcelist.h>
 #include <apt-pkg/sourcelist.h>
-#include <apt-pkg/vendorlist.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/fileutl.h>
@@ -1390,29 +1389,6 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify)				/*{{{*/
 									/*}}}*/
 									/*}}}*/
 bool pkgAcqMetaIndex::VerifyVendor(string Message)			/*{{{*/
 bool pkgAcqMetaIndex::VerifyVendor(string Message)			/*{{{*/
 {
 {
-//    // Maybe this should be made available from above so we don't have
-//    // to read and parse it every time?
-//    pkgVendorList List;
-//    List.ReadMainList();
-
-//    const Vendor* Vndr = NULL;
-//    for (std::vector<string>::const_iterator I = GPGVOutput.begin(); I != GPGVOutput.end(); I++)
-//    {
-//       string::size_type pos = (*I).find("VALIDSIG ");
-//       if (_config->FindB("Debug::Vendor", false))
-//          std::cerr << "Looking for VALIDSIG in \"" << (*I) << "\": pos " << pos 
-//                    << std::endl;
-//       if (pos != std::string::npos)
-//       {
-//          string Fingerprint = (*I).substr(pos+sizeof("VALIDSIG"));
-//          if (_config->FindB("Debug::Vendor", false))
-//             std::cerr << "Looking for \"" << Fingerprint << "\" in vendor..." <<
-//                std::endl;
-//          Vndr = List.FindVendor(Fingerprint) != "";
-//          if (Vndr != NULL);
-//          break;
-//       }
-//    }
    string::size_type pos;
    string::size_type pos;
 
 
    // check for missing sigs (that where not fatal because otherwise we had
    // check for missing sigs (that where not fatal because otherwise we had

+ 1 - 1
apt-pkg/algorithms.h

@@ -108,7 +108,7 @@ class pkgProblemResolver						/*{{{*/
    
    
    public:
    public:
    
    
-   inline void Protect(pkgCache::PkgIterator Pkg) {Flags[Pkg->ID] |= Protected;};
+   inline void Protect(pkgCache::PkgIterator Pkg) {Flags[Pkg->ID] |= Protected; Cache.MarkProtected(Pkg);};
    inline void Remove(pkgCache::PkgIterator Pkg) {Flags[Pkg->ID] |= ToRemove;};
    inline void Remove(pkgCache::PkgIterator Pkg) {Flags[Pkg->ID] |= ToRemove;};
    inline void Clear(pkgCache::PkgIterator Pkg) {Flags[Pkg->ID] &= ~(Protected | ToRemove);};
    inline void Clear(pkgCache::PkgIterator Pkg) {Flags[Pkg->ID] &= ~(Protected | ToRemove);};
    
    

+ 32 - 1
apt-pkg/aptconfiguration.cc

@@ -17,6 +17,7 @@
 
 
 #include <sys/types.h>
 #include <sys/types.h>
 #include <dirent.h>
 #include <dirent.h>
+#include <stdio.h>
 
 
 #include <algorithm>
 #include <algorithm>
 #include <string>
 #include <string>
@@ -314,11 +315,41 @@ std::vector<std::string> const Configuration::getArchitectures(bool const &Cache
 	if (likely(Cached == true) && archs.empty() == false)
 	if (likely(Cached == true) && archs.empty() == false)
 		return archs;
 		return archs;
 
 
-	archs = _config->FindVector("APT::Architectures");
 	string const arch = _config->Find("APT::Architecture");
 	string const arch = _config->Find("APT::Architecture");
+	archs = _config->FindVector("APT::Architectures");
+
 	if (unlikely(arch.empty() == true))
 	if (unlikely(arch.empty() == true))
 		return archs;
 		return archs;
 
 
+	// FIXME: It is a bit unclean to have debian specific code here…
+	if (archs.empty() == true) {
+		archs.push_back(arch);
+		string dpkgcall = _config->Find("Dir::Bin::dpkg", "dpkg");
+		std::vector<string> const dpkgoptions = _config->FindVector("DPkg::options");
+		for (std::vector<string>::const_iterator o = dpkgoptions.begin();
+		     o != dpkgoptions.end(); ++o)
+			dpkgcall.append(" ").append(*o);
+		dpkgcall.append(" --print-foreign-architectures 2> /dev/null");
+		FILE *dpkg = popen(dpkgcall.c_str(), "r");
+		char buf[1024];
+		if(dpkg != NULL) {
+			if (fgets(buf, sizeof(buf), dpkg) != NULL) {
+				char* arch = strtok(buf, " ");
+				while (arch != NULL) {
+					for (; isspace(*arch) != 0; ++arch);
+					if (arch != '\0') {
+						char const* archend = arch;
+						for (; isspace(*archend) == 0 && *archend != '\0'; ++archend);
+						archs.push_back(string(arch, (archend - arch)));
+					}
+					arch = strtok(NULL, " ");
+				}
+			}
+			pclose(dpkg);
+		}
+		return archs;
+	}
+
 	if (archs.empty() == true ||
 	if (archs.empty() == true ||
 	    std::find(archs.begin(), archs.end(), arch) == archs.end())
 	    std::find(archs.begin(), archs.end(), arch) == archs.end())
 		archs.push_back(arch);
 		archs.push_back(arch);

+ 4 - 0
apt-pkg/cacheiterators.h

@@ -206,6 +206,10 @@ class pkgCache::VerIterator : public Iterator<Version, VerIterator> {
 	inline const char *VerStr() const {return S->VerStr == 0?0:Owner->StrP + S->VerStr;};
 	inline const char *VerStr() const {return S->VerStr == 0?0:Owner->StrP + S->VerStr;};
 	inline const char *Section() const {return S->Section == 0?0:Owner->StrP + S->Section;};
 	inline const char *Section() const {return S->Section == 0?0:Owner->StrP + S->Section;};
 	inline const char *Arch() const {
 	inline const char *Arch() const {
+		if (S->MultiArch == pkgCache::Version::All ||
+		    S->MultiArch == pkgCache::Version::AllForeign ||
+		    S->MultiArch == pkgCache::Version::AllAllowed)
+			return "all";
 		return S->ParentPkg == 0?0:Owner->StrP + ParentPkg()->Arch;
 		return S->ParentPkg == 0?0:Owner->StrP + ParentPkg()->Arch;
 	};
 	};
 	__deprecated inline const char *Arch(bool const pseudo) const {
 	__deprecated inline const char *Arch(bool const pseudo) const {

+ 5 - 3
apt-pkg/contrib/strutl.cc

@@ -692,14 +692,16 @@ int StringToBool(const string &Text,int Default)
    year 2000 complient and timezone neutral */
    year 2000 complient and timezone neutral */
 string TimeRFC1123(time_t Date)
 string TimeRFC1123(time_t Date)
 {
 {
-   struct tm Conv = *gmtime(&Date);
-   char Buf[300];
+   struct tm Conv;
+   if (gmtime_r(&Date, &Conv) == NULL)
+      return "";
 
 
+   char Buf[300];
    const char *Day[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
    const char *Day[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
    const char *Month[] = {"Jan","Feb","Mar","Apr","May","Jun","Jul",
    const char *Month[] = {"Jan","Feb","Mar","Apr","May","Jun","Jul",
                           "Aug","Sep","Oct","Nov","Dec"};
                           "Aug","Sep","Oct","Nov","Dec"};
 
 
-   sprintf(Buf,"%s, %02i %s %i %02i:%02i:%02i GMT",Day[Conv.tm_wday],
+   snprintf(Buf, sizeof(Buf), "%s, %02i %s %i %02i:%02i:%02i GMT",Day[Conv.tm_wday],
 	   Conv.tm_mday,Month[Conv.tm_mon],Conv.tm_year+1900,Conv.tm_hour,
 	   Conv.tm_mday,Month[Conv.tm_mon],Conv.tm_year+1900,Conv.tm_hour,
 	   Conv.tm_min,Conv.tm_sec);
 	   Conv.tm_min,Conv.tm_sec);
    return Buf;
    return Buf;

+ 22 - 13
apt-pkg/deb/deblistparser.cc

@@ -106,7 +106,7 @@ bool debListParser::NewVersion(pkgCache::VerIterator &Ver)
       Ver->MultiArch = pkgCache::Version::None;
       Ver->MultiArch = pkgCache::Version::None;
    else if (MultiArch == "same") {
    else if (MultiArch == "same") {
       // Parse multi-arch
       // Parse multi-arch
-      if (Section.FindS("Architecture") == "all")
+      if (ArchitectureAll() == true)
       {
       {
 	 /* Arch all packages can't be Multi-Arch: same */
 	 /* Arch all packages can't be Multi-Arch: same */
 	 _error->Warning("Architecture: all package '%s' can't be Multi-Arch: same",
 	 _error->Warning("Architecture: all package '%s' can't be Multi-Arch: same",
@@ -127,6 +127,14 @@ bool debListParser::NewVersion(pkgCache::VerIterator &Ver)
       Ver->MultiArch = pkgCache::Version::None;
       Ver->MultiArch = pkgCache::Version::None;
    }
    }
 
 
+   if (ArchitectureAll() == true)
+      switch (Ver->MultiArch)
+      {
+	 case pkgCache::Version::Foreign: Ver->MultiArch = pkgCache::Version::AllForeign; break;
+	 case pkgCache::Version::Allowed: Ver->MultiArch = pkgCache::Version::AllAllowed; break;
+	 default: Ver->MultiArch = pkgCache::Version::All;
+      }
+
    // Archive Size
    // Archive Size
    Ver->Size = Section.FindULL("Size");
    Ver->Size = Section.FindULL("Size");
    // Unpacked Size (in K)
    // Unpacked Size (in K)
@@ -624,7 +632,7 @@ bool debListParser::ParseDepends(pkgCache::VerIterator &Ver,
 
 
    while (1)
    while (1)
    {
    {
-      Start = ParseDepends(Start,Stop,Package,Version,Op);
+      Start = ParseDepends(Start,Stop,Package,Version,Op,false,!MultiArchEnabled);
       if (Start == 0)
       if (Start == 0)
 	 return _error->Error("Problem parsing dependency %s",Tag);
 	 return _error->Error("Problem parsing dependency %s",Tag);
 
 
@@ -677,27 +685,28 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver)
       }
       }
    }
    }
 
 
-   if (Ver->MultiArch == pkgCache::Version::Allowed)
+   if (MultiArchEnabled == false)
+      return true;
+   else if (Ver->MultiArch == pkgCache::Version::Allowed || Ver->MultiArch == pkgCache::Version::AllAllowed)
    {
    {
       string const Package = string(Ver.ParentPkg().Name()).append(":").append("any");
       string const Package = string(Ver.ParentPkg().Name()).append(":").append("any");
-      NewProvides(Ver, Package, "any", Ver.VerStr());
+      return NewProvidesAllArch(Ver, Package, Ver.VerStr());
    }
    }
+   else if (Ver->MultiArch == pkgCache::Version::Foreign || Ver->MultiArch == pkgCache::Version::AllForeign)
+      return NewProvidesAllArch(Ver, Ver.ParentPkg().Name(), Ver.VerStr());
 
 
-   if (Ver->MultiArch != pkgCache::Version::Foreign)
-      return true;
-
-   if (MultiArchEnabled == false)
-      return true;
-
-   string const Package = Ver.ParentPkg().Name();
-   string const Version = Ver.VerStr();
+   return true;
+}
+									/*}}}*/
+// ListParser::NewProvides - add provides for all architectures		/*{{{*/
+bool debListParser::NewProvidesAllArch(pkgCache::VerIterator &Ver, string const &Package,
+				string const &Version) {
    for (std::vector<string>::const_iterator a = Architectures.begin();
    for (std::vector<string>::const_iterator a = Architectures.begin();
 	a != Architectures.end(); ++a)
 	a != Architectures.end(); ++a)
    {
    {
       if (NewProvides(Ver, Package, *a, Version) == false)
       if (NewProvides(Ver, Package, *a, Version) == false)
 	 return false;
 	 return false;
    }
    }
-
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/

+ 2 - 1
apt-pkg/deb/deblistparser.h

@@ -40,6 +40,7 @@ class debListParser : public pkgCacheGenerator::ListParser
    bool ParseDepends(pkgCache::VerIterator &Ver,const char *Tag,
    bool ParseDepends(pkgCache::VerIterator &Ver,const char *Tag,
 		     unsigned int Type);
 		     unsigned int Type);
    bool ParseProvides(pkgCache::VerIterator &Ver);
    bool ParseProvides(pkgCache::VerIterator &Ver);
+   bool NewProvidesAllArch(pkgCache::VerIterator &Ver, string const &Package, string const &Version);
    static bool GrabWord(string Word,WordList *List,unsigned char &Out);
    static bool GrabWord(string Word,WordList *List,unsigned char &Out);
    
    
    public:
    public:
@@ -69,7 +70,7 @@ class debListParser : public pkgCacheGenerator::ListParser
    static const char *ParseDepends(const char *Start,const char *Stop,
    static const char *ParseDepends(const char *Start,const char *Stop,
 			    string &Package,string &Ver,unsigned int &Op,
 			    string &Package,string &Ver,unsigned int &Op,
 			    bool const &ParseArchFlags = false,
 			    bool const &ParseArchFlags = false,
-			    bool const &StripMultiArch = false);
+			    bool const &StripMultiArch = true);
    static const char *ConvertRelation(const char *I,unsigned int &Op);
    static const char *ConvertRelation(const char *I,unsigned int &Op);
 
 
    debListParser(FileFd *File, string const &Arch = "");
    debListParser(FileFd *File, string const &Arch = "");

+ 6 - 2
apt-pkg/deb/dpkgpm.cc

@@ -1002,6 +1002,7 @@ bool pkgDPkgPM::Go(int OutStatusFd)
       else
       else
       {
       {
 	 string const nativeArch = _config->Find("APT::Architecture");
 	 string const nativeArch = _config->Find("APT::Architecture");
+	 unsigned long const oldSize = I->Op == Item::Configure ? Size : 0;
 	 for (;I != J && Size < MaxArgBytes; I++)
 	 for (;I != J && Size < MaxArgBytes; I++)
 	 {
 	 {
 	    if((*I).Pkg.end() == true)
 	    if((*I).Pkg.end() == true)
@@ -1016,8 +1017,11 @@ bool pkgDPkgPM::Go(int OutStatusFd)
 	       Args[n++] = Packages[pkgcount++];
 	       Args[n++] = Packages[pkgcount++];
 	    }
 	    }
 	    Size += strlen(Args[n-1]);
 	    Size += strlen(Args[n-1]);
-	 }	 
-      }      
+	 }
+	 // skip configure action if all sheduled packages disappeared
+	 if (oldSize == Size)
+	    continue;
+      }
       Args[n] = 0;
       Args[n] = 0;
       J = I;
       J = I;
       
       

+ 86 - 64
apt-pkg/depcache.cc

@@ -819,8 +819,7 @@ void pkgDepCache::Update(PkgIterator const &Pkg)
 void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser,
 void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser,
                            unsigned long Depth)
                            unsigned long Depth)
 {
 {
-   // Simplifies other routines.
-   if (Pkg.end() == true)
+   if (IsModeChangeOk(ModeKeep, Pkg, Depth, FromUser) == false)
       return;
       return;
 
 
    /* Reject an attempt to keep a non-source broken installed package, those
    /* Reject an attempt to keep a non-source broken installed package, those
@@ -828,25 +827,22 @@ void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser,
    if (Pkg.State() == PkgIterator::NeedsUnpack && 
    if (Pkg.State() == PkgIterator::NeedsUnpack && 
        Pkg.CurrentVer().Downloadable() == false)
        Pkg.CurrentVer().Downloadable() == false)
       return;
       return;
-   
-   /** \todo Can this be moved later in the method? */
-   ActionGroup group(*this);
 
 
    /* We changed the soft state all the time so the UI is a bit nicer
    /* We changed the soft state all the time so the UI is a bit nicer
       to use */
       to use */
    StateCache &P = PkgState[Pkg->ID];
    StateCache &P = PkgState[Pkg->ID];
+
+   // Check that it is not already kept
+   if (P.Mode == ModeKeep)
+      return;
+
    if (Soft == true)
    if (Soft == true)
       P.iFlags |= AutoKept;
       P.iFlags |= AutoKept;
    else
    else
       P.iFlags &= ~AutoKept;
       P.iFlags &= ~AutoKept;
-   
-   // Check that it is not already kept
-   if (P.Mode == ModeKeep)
-      return;
 
 
-   // We dont even try to keep virtual packages..
-   if (Pkg->VersionList == 0)
-      return;
+   ActionGroup group(*this);
+
 #if 0 // reseting the autoflag here means we lose the 
 #if 0 // reseting the autoflag here means we lose the 
       // auto-mark information if a user selects a package for removal
       // auto-mark information if a user selects a package for removal
       // but changes  his mind then and sets it for keep again
       // but changes  his mind then and sets it for keep again
@@ -883,30 +879,26 @@ void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser,
 void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge,
 void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge,
                              unsigned long Depth, bool FromUser)
                              unsigned long Depth, bool FromUser)
 {
 {
-   // Simplifies other routines.
-   if (Pkg.end() == true)
+   if (IsModeChangeOk(ModeDelete, Pkg, Depth, FromUser) == false)
       return;
       return;
 
 
-   ActionGroup group(*this);
+   StateCache &P = PkgState[Pkg->ID];
 
 
    // Check that it is not already marked for delete
    // Check that it is not already marked for delete
-   StateCache &P = PkgState[Pkg->ID];
-   P.iFlags &= ~(AutoKept | Purge);
-   if (rPurge == true)
-      P.iFlags |= Purge;
-   
    if ((P.Mode == ModeDelete || P.InstallVer == 0) && 
    if ((P.Mode == ModeDelete || P.InstallVer == 0) && 
        (Pkg.Purge() == true || rPurge == false))
        (Pkg.Purge() == true || rPurge == false))
       return;
       return;
-   
-   // We dont even try to delete virtual packages..
-   if (Pkg->VersionList == 0)
-      return;
 
 
-   // check if we are allowed to install the package
+   // check if we are allowed to remove the package
    if (IsDeleteOk(Pkg,rPurge,Depth,FromUser) == false)
    if (IsDeleteOk(Pkg,rPurge,Depth,FromUser) == false)
       return;
       return;
 
 
+   P.iFlags &= ~(AutoKept | Purge);
+   if (rPurge == true)
+      P.iFlags |= Purge;
+
+   ActionGroup group(*this);
+
    if (DebugMarker == true)
    if (DebugMarker == true)
       std::clog << OutputInDepth(Depth) << (rPurge ? "MarkPurge " : "MarkDelete ") << Pkg << " FU=" << FromUser << std::endl;
       std::clog << OutputInDepth(Depth) << (rPurge ? "MarkPurge " : "MarkDelete ") << Pkg << " FU=" << FromUser << std::endl;
 
 
@@ -927,19 +919,12 @@ void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge,
 									/*}}}*/
 									/*}}}*/
 // DepCache::IsDeleteOk - check if it is ok to remove this package	/*{{{*/
 // DepCache::IsDeleteOk - check if it is ok to remove this package	/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
-/* The default implementation just honors dpkg hold
-   But an application using this library can override this method
-   to control the MarkDelete behaviour */
+/* The default implementation tries to prevent deletion of install requests.
+   dpkg holds are enforced by the private IsModeChangeOk */
 bool pkgDepCache::IsDeleteOk(PkgIterator const &Pkg,bool rPurge,
 bool pkgDepCache::IsDeleteOk(PkgIterator const &Pkg,bool rPurge,
 			      unsigned long Depth, bool FromUser)
 			      unsigned long Depth, bool FromUser)
 {
 {
-   if (FromUser == false && Pkg->SelectedState == pkgCache::State::Hold && _config->FindB("APT::Ignore-Hold",false) == false)
-   {
-      if (DebugMarker == true)
-	 std::clog << OutputInDepth(Depth) << "Hold prevents MarkDelete of " << Pkg << " FU=" << FromUser << std::endl;
-      return false;
-   }
-   else if (FromUser == false && Pkg->CurrentVer == 0)
+   if (FromUser == false && Pkg->CurrentVer == 0)
    {
    {
       StateCache &P = PkgState[Pkg->ID];
       StateCache &P = PkgState[Pkg->ID];
       if (P.InstallVer != 0 && P.Status == 2 && (P.Flags & Flag::Auto) != Flag::Auto)
       if (P.InstallVer != 0 && P.Status == 2 && (P.Flags & Flag::Auto) != Flag::Auto)
@@ -949,6 +934,61 @@ bool pkgDepCache::IsDeleteOk(PkgIterator const &Pkg,bool rPurge,
 	 return false;
 	 return false;
       }
       }
    }
    }
+   return true;
+}
+									/*}}}*/
+// DepCache::IsModeChangeOk - check if it is ok to change the mode	/*{{{*/
+// ---------------------------------------------------------------------
+/* this is used by all Mark methods on the very first line to check sanity
+   and prevents mode changes for packages on hold for example.
+   If you want to check Mode specific stuff you can use the virtual public
+   Is<Mode>Ok methods instead */
+char const* PrintMode(char const mode)
+{
+	 switch (mode)
+	 {
+	 case pkgDepCache::ModeInstall: return "Install";
+	 case pkgDepCache::ModeKeep: return "Keep";
+	 case pkgDepCache::ModeDelete: return "Delete";
+	 default: return "UNKNOWN";
+	 }
+}
+bool pkgDepCache::IsModeChangeOk(ModeList const mode, PkgIterator const &Pkg,
+				 unsigned long const Depth, bool const FromUser)
+{
+   // we are not trying to hard…
+   if (unlikely(Depth > 100))
+      return false;
+
+   // general sanity
+   if (unlikely(Pkg.end() == true || Pkg->VersionList == 0))
+      return false;
+
+   // the user is always right
+   if (FromUser == true)
+      return true;
+
+   StateCache &P = PkgState[Pkg->ID];
+
+   // if previous state was set by user only user can reset it
+   if ((P.iFlags & Protected) == Protected)
+   {
+      if (unlikely(DebugMarker == true) && P.Mode != mode)
+	 std::clog << OutputInDepth(Depth) << "Ignore Mark" << PrintMode(mode)
+		   << " of " << Pkg << " as its mode (" << PrintMode(P.Mode)
+		   << ") is protected" << std::endl;
+      return false;
+   }
+   // enforce dpkg holds
+   else if (mode != ModeKeep && Pkg->SelectedState == pkgCache::State::Hold &&
+	    _config->FindB("APT::Ignore-Hold",false) == false)
+   {
+      if (unlikely(DebugMarker == true) && P.Mode != mode)
+	 std::clog << OutputInDepth(Depth) << "Hold prevents Mark" << PrintMode(mode)
+		   << " of " << Pkg << std::endl;
+      return false;
+   }
+
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -959,19 +999,17 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
 			      unsigned long Depth, bool FromUser,
 			      unsigned long Depth, bool FromUser,
 			      bool ForceImportantDeps)
 			      bool ForceImportantDeps)
 {
 {
-   if (Depth > 100)
+   if (IsModeChangeOk(ModeInstall, Pkg, Depth, FromUser) == false)
       return;
       return;
-   
-   // Simplifies other routines.
-   if (Pkg.end() == true)
+
+   StateCache &P = PkgState[Pkg->ID];
+
+   // See if there is even any possible instalation candidate
+   if (P.CandidateVer == 0)
       return;
       return;
-   
-   ActionGroup group(*this);
 
 
    /* Check that it is not already marked for install and that it can be 
    /* Check that it is not already marked for install and that it can be 
       installed */
       installed */
-   StateCache &P = PkgState[Pkg->ID];
-   P.iFlags &= ~AutoKept;
    if ((P.InstPolicyBroken() == false && P.InstBroken() == false) && 
    if ((P.InstPolicyBroken() == false && P.InstBroken() == false) && 
        (P.Mode == ModeInstall ||
        (P.Mode == ModeInstall ||
 	P.CandidateVer == (Version *)Pkg.CurrentVer()))
 	P.CandidateVer == (Version *)Pkg.CurrentVer()))
@@ -981,17 +1019,13 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
       return;
       return;
    }
    }
 
 
-   // See if there is even any possible instalation candidate
-   if (P.CandidateVer == 0)
-      return;
-   // We dont even try to install virtual packages..
-   if (Pkg->VersionList == 0)
-      return;
-
    // check if we are allowed to install the package
    // check if we are allowed to install the package
    if (IsInstallOk(Pkg,AutoInst,Depth,FromUser) == false)
    if (IsInstallOk(Pkg,AutoInst,Depth,FromUser) == false)
       return;
       return;
 
 
+   ActionGroup group(*this);
+   P.iFlags &= ~AutoKept;
+
    /* Target the candidate version and remove the autoflag. We reset the
    /* Target the candidate version and remove the autoflag. We reset the
       autoflag below if this was called recursively. Otherwise the user
       autoflag below if this was called recursively. Otherwise the user
       should have the ability to de-auto a package by changing its state */
       should have the ability to de-auto a package by changing its state */
@@ -1204,18 +1238,11 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
 									/*}}}*/
 									/*}}}*/
 // DepCache::IsInstallOk - check if it is ok to install this package	/*{{{*/
 // DepCache::IsInstallOk - check if it is ok to install this package	/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
-/* The default implementation just honors dpkg hold
-   But an application using this library can override this method
-   to control the MarkInstall behaviour */
+/* The default implementation does nothing.
+   dpkg holds are enforced by the private IsModeChangeOk */
 bool pkgDepCache::IsInstallOk(PkgIterator const &Pkg,bool AutoInst,
 bool pkgDepCache::IsInstallOk(PkgIterator const &Pkg,bool AutoInst,
 			      unsigned long Depth, bool FromUser)
 			      unsigned long Depth, bool FromUser)
 {
 {
-   if (FromUser == false && Pkg->SelectedState == pkgCache::State::Hold && _config->FindB("APT::Ignore-Hold",false) == false)
-   {
-      if (DebugMarker == true)
-	 std::clog << OutputInDepth(Depth) << "Hold prevents MarkInstall of " << Pkg << " FU=" << FromUser << std::endl;
-      return false;
-   }
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -1240,11 +1267,6 @@ void pkgDepCache::SetReInstall(PkgIterator const &Pkg,bool To)
    
    
    AddStates(Pkg);
    AddStates(Pkg);
    AddSizes(Pkg);
    AddSizes(Pkg);
-
-   if (unlikely(Pkg.CurrentVer().end() == true))
-      return;
-
-   SetReInstall(Pkg.Group().FindPkg("all"), To);
 }
 }
 									/*}}}*/
 									/*}}}*/
 // DepCache::SetCandidateVersion - Change the candidate version		/*{{{*/
 // DepCache::SetCandidateVersion - Change the candidate version		/*{{{*/

+ 6 - 1
apt-pkg/depcache.h

@@ -119,7 +119,7 @@ class pkgDepCache : protected pkgCache::Namespace
                        DepCandPolicy = (1 << 4), DepCandMin = (1 << 5)};
                        DepCandPolicy = (1 << 4), DepCandMin = (1 << 5)};
    
    
    // These flags are used in StateCache::iFlags
    // These flags are used in StateCache::iFlags
-   enum InternalFlags {AutoKept = (1 << 0), Purge = (1 << 1), ReInstall = (1 << 2)};
+   enum InternalFlags {AutoKept = (1 << 0), Purge = (1 << 1), ReInstall = (1 << 2), Protected = (1 << 3)};
       
       
    enum VersionTypes {NowVersion, InstallVersion, CandidateVersion};
    enum VersionTypes {NowVersion, InstallVersion, CandidateVersion};
    enum ModeList {ModeDelete = 0, ModeKeep = 1, ModeInstall = 2};
    enum ModeList {ModeDelete = 0, ModeKeep = 1, ModeInstall = 2};
@@ -393,6 +393,7 @@ class pkgDepCache : protected pkgCache::Namespace
    void MarkInstall(PkgIterator const &Pkg,bool AutoInst = true,
    void MarkInstall(PkgIterator const &Pkg,bool AutoInst = true,
 		    unsigned long Depth = 0, bool FromUser = true,
 		    unsigned long Depth = 0, bool FromUser = true,
 		    bool ForceImportantDeps = false);
 		    bool ForceImportantDeps = false);
+   void MarkProtected(PkgIterator const &Pkg) { PkgState[Pkg->ID].iFlags |= Protected; };
 
 
    void SetReInstall(PkgIterator const &Pkg,bool To);
    void SetReInstall(PkgIterator const &Pkg,bool To);
    // FIXME: Remove the unused boolean parameter on abi break
    // FIXME: Remove the unused boolean parameter on abi break
@@ -486,6 +487,10 @@ class pkgDepCache : protected pkgCache::Namespace
    __deprecated bool RemovePseudoInstalledPkg(PkgIterator &Pkg, std::set<unsigned long> &recheck) { return true; };
    __deprecated bool RemovePseudoInstalledPkg(PkgIterator &Pkg, std::set<unsigned long> &recheck) { return true; };
    __deprecated bool ReInstallPseudoForGroup(unsigned long const &Grp, std::set<unsigned long> &recheck) { return true; };
    __deprecated bool ReInstallPseudoForGroup(unsigned long const &Grp, std::set<unsigned long> &recheck) { return true; };
    __deprecated bool ReInstallPseudoForGroup(pkgCache::PkgIterator const &P, std::set<unsigned long> &recheck) { return true; };
    __deprecated bool ReInstallPseudoForGroup(pkgCache::PkgIterator const &P, std::set<unsigned long> &recheck) { return true; };
+
+
+   bool IsModeChangeOk(ModeList const mode, PkgIterator const &Pkg,
+			unsigned long const Depth, bool const FromUser);
 };
 };
 
 
 #endif
 #endif

+ 6 - 6
apt-pkg/pkgcache.cc

@@ -317,22 +317,22 @@ pkgCache::PkgIterator pkgCache::GrpIterator::FindPkg(string Arch) const {
 	if (unlikely(IsGood() == false || S->FirstPackage == 0))
 	if (unlikely(IsGood() == false || S->FirstPackage == 0))
 		return PkgIterator(*Owner, 0);
 		return PkgIterator(*Owner, 0);
 
 
+	/* If we accept any package we simply return the "first"
+	   package in this group (the last one added). */
+	if (Arch == "any")
+		return PkgIterator(*Owner, Owner->PkgP + S->FirstPackage);
+
 	static string const myArch = _config->Find("APT::Architecture");
 	static string const myArch = _config->Find("APT::Architecture");
 	/* Most of the time the package for our native architecture is
 	/* Most of the time the package for our native architecture is
 	   the one we add at first to the cache, but this would be the
 	   the one we add at first to the cache, but this would be the
 	   last one we check, so we do it now. */
 	   last one we check, so we do it now. */
-	if (Arch == "native" || Arch == myArch) {
+	if (Arch == "native" || Arch == myArch || Arch == "all") {
 		Arch = myArch;
 		Arch = myArch;
 		pkgCache::Package *Pkg = Owner->PkgP + S->LastPackage;
 		pkgCache::Package *Pkg = Owner->PkgP + S->LastPackage;
 		if (stringcasecmp(Arch, Owner->StrP + Pkg->Arch) == 0)
 		if (stringcasecmp(Arch, Owner->StrP + Pkg->Arch) == 0)
 			return PkgIterator(*Owner, Pkg);
 			return PkgIterator(*Owner, Pkg);
 	}
 	}
 
 
-	/* If we accept any package we simply return the "first"
-	   package in this group (the last one added). */
-	if (Arch == "any")
-		return PkgIterator(*Owner, Owner->PkgP + S->FirstPackage);
-
 	/* Iterate over the list to find the matching arch
 	/* Iterate over the list to find the matching arch
 	   unfortunately this list includes "package noise"
 	   unfortunately this list includes "package noise"
 	   (= different packages with same calculated hash),
 	   (= different packages with same calculated hash),

+ 2 - 2
apt-pkg/pkgcache.h

@@ -506,8 +506,8 @@ struct pkgCache::Version
        if it is built for another architecture as the requester.
        if it is built for another architecture as the requester.
        Same indicates that builds for different architectures can
        Same indicates that builds for different architectures can
        be co-installed on the system */
        be co-installed on the system */
-   // FIXME: remove All on abi break
-   enum {None, All, Foreign, Same, Allowed} MultiArch;
+   /* FIXME: A bitflag would be better with the next abibreak… */
+   enum {None, All, Foreign, Same, Allowed, AllForeign, AllAllowed} MultiArch;
 
 
    /** \brief references all the PackageFile's that this version came from
    /** \brief references all the PackageFile's that this version came from
 
 

+ 5 - 9
apt-pkg/pkgcachegen.cc

@@ -178,12 +178,7 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
       if (PackageName.empty() == true)
       if (PackageName.empty() == true)
 	 return false;
 	 return false;
 
 
-      /* Treat Arch all packages as the same as the native arch. */
-      string Arch;
-      if (List.ArchitectureAll() == true)
-	 Arch = _config->Find("APT::Architecture");
-      else
-	 Arch = List.Architecture();
+      string const Arch = List.Architecture();
  
  
       // Get a pointer to the package structure
       // Get a pointer to the package structure
       pkgCache::PkgIterator Pkg;
       pkgCache::PkgIterator Pkg;
@@ -484,7 +479,7 @@ bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const string &Name
    // Set the name, arch and the ID
    // Set the name, arch and the ID
    Pkg->Name = Grp->Name;
    Pkg->Name = Grp->Name;
    Pkg->Group = Grp.Index();
    Pkg->Group = Grp.Index();
-   map_ptrloc const idxArch = WriteUniqString(Arch.c_str());
+   map_ptrloc const idxArch = WriteUniqString((Arch == "all") ? _config->Find("APT::Architecture") : Arch.c_str());
    if (unlikely(idxArch == 0))
    if (unlikely(idxArch == 0))
       return false;
       return false;
    Pkg->Arch = idxArch;
    Pkg->Arch = idxArch;
@@ -643,7 +638,7 @@ bool pkgCacheGenerator::FinishCache(OpProgress *Progress)
 		- MultiArch: same → Co-Installable if they have the same version
 		- MultiArch: same → Co-Installable if they have the same version
 		- Architecture: all → Need to be Co-Installable for internal reasons
 		- Architecture: all → Need to be Co-Installable for internal reasons
 		- All others conflict with all other group members */
 		- All others conflict with all other group members */
-	       bool const coInstall = (V->MultiArch == pkgCache::Version::Same);
+	       bool const coInstall = ((V->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same);
 	       for (vector<string>::const_iterator A = archs.begin(); A != archs.end(); ++A)
 	       for (vector<string>::const_iterator A = archs.begin(); A != archs.end(); ++A)
 	       {
 	       {
 		  if (*A == Arch)
 		  if (*A == Arch)
@@ -787,7 +782,8 @@ bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator &Ver,
    pkgCache &Cache = Owner->Cache;
    pkgCache &Cache = Owner->Cache;
 
 
    // We do not add self referencing provides
    // We do not add self referencing provides
-   if (Ver.ParentPkg().Name() == PkgName && PkgArch == Ver.Arch())
+   if (Ver.ParentPkg().Name() == PkgName && (PkgArch == Ver.ParentPkg().Arch() ||
+	(PkgArch == "all" && _config->Find("APT::Architecture") == Ver.ParentPkg().Arch())))
       return true;
       return true;
    
    
    // Get a structure
    // Get a structure

+ 2 - 1
apt-pkg/vendor.h

@@ -4,11 +4,12 @@
 #include <vector>
 #include <vector>
 #include <map>
 #include <map>
 
 
+#include <apt-pkg/macros.h>
 
 
 using std::string;
 using std::string;
 
 
 // A class representing a particular software provider. 
 // A class representing a particular software provider. 
-class Vendor
+class __deprecated Vendor
 {
 {
    public:
    public:
    struct Fingerprint
    struct Fingerprint

+ 10 - 1
apt-pkg/vendorlist.cc

@@ -1,8 +1,13 @@
-#include <apt-pkg/vendorlist.h>
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 #include <apti18n.h>
 #include <apti18n.h>
 
 
+#if __GNUC__ >= 4
+	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
+
+#include <apt-pkg/vendorlist.h>
+
 pkgVendorList::~pkgVendorList()
 pkgVendorList::~pkgVendorList()
 {
 {
    for (vector<const Vendor *>::const_iterator I = VendorList.begin(); 
    for (vector<const Vendor *>::const_iterator I = VendorList.begin(); 
@@ -143,3 +148,7 @@ const Vendor* pkgVendorList::FindVendor(const std::vector<string> GPGVOutput)	/*
    return NULL;
    return NULL;
 }
 }
 									/*}}}*/
 									/*}}}*/
+
+#if __GNUC__ >= 4
+	#pragma GCC diagnostic warning "-Wdeprecated-declarations"
+#endif

+ 2 - 1
apt-pkg/vendorlist.h

@@ -17,12 +17,13 @@
 #include <vector>
 #include <vector>
 #include <apt-pkg/vendor.h>
 #include <apt-pkg/vendor.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/configuration.h>
+#include <apt-pkg/macros.h>
 
 
 using std::string;
 using std::string;
 using std::vector;
 using std::vector;
 
 
 
 
-class pkgVendorList
+class __deprecated pkgVendorList
 {
 {
    protected:
    protected:
    vector<Vendor const *> VendorList;
    vector<Vendor const *> VendorList;

+ 50 - 21
cmdline/apt-get.cc

@@ -764,7 +764,7 @@ struct TryToInstall {
    unsigned long AutoMarkChanged;
    unsigned long AutoMarkChanged;
    APT::PackageSet doAutoInstallLater;
    APT::PackageSet doAutoInstallLater;
 
 
-   TryToInstall(pkgCacheFile &Cache, pkgProblemResolver &PM, bool const &FixBroken) : Cache(&Cache), Fix(&PM),
+   TryToInstall(pkgCacheFile &Cache, pkgProblemResolver *PM, bool const &FixBroken) : Cache(&Cache), Fix(PM),
 			FixBroken(FixBroken), AutoMarkChanged(0) {};
 			FixBroken(FixBroken), AutoMarkChanged(0) {};
 
 
    void operator() (pkgCache::VerIterator const &Ver) {
    void operator() (pkgCache::VerIterator const &Ver) {
@@ -782,8 +782,10 @@ struct TryToInstall {
 	 ioprintf(c1out,_("Skipping %s, it is not installed and only upgrades are requested.\n"),
 	 ioprintf(c1out,_("Skipping %s, it is not installed and only upgrades are requested.\n"),
 		  Pkg.FullName(true).c_str());
 		  Pkg.FullName(true).c_str());
       else {
       else {
-	 Fix->Clear(Pkg);
-	 Fix->Protect(Pkg);
+	 if (Fix != NULL) {
+	    Fix->Clear(Pkg);
+	    Fix->Protect(Pkg);
+	 }
 	 Cache->GetDepCache()->MarkInstall(Pkg,false);
 	 Cache->GetDepCache()->MarkInstall(Pkg,false);
 
 
 	 if (State.Install() == false) {
 	 if (State.Install() == false) {
@@ -871,16 +873,19 @@ struct TryToRemove {
    bool PurgePkgs;
    bool PurgePkgs;
    unsigned long AutoMarkChanged;
    unsigned long AutoMarkChanged;
 
 
-   TryToRemove(pkgCacheFile &Cache, pkgProblemResolver &PM) : Cache(&Cache), Fix(&PM),
+   TryToRemove(pkgCacheFile &Cache, pkgProblemResolver *PM) : Cache(&Cache), Fix(PM),
 				PurgePkgs(_config->FindB("APT::Get::Purge", false)) {};
 				PurgePkgs(_config->FindB("APT::Get::Purge", false)) {};
 
 
    void operator() (pkgCache::VerIterator const &Ver)
    void operator() (pkgCache::VerIterator const &Ver)
    {
    {
       pkgCache::PkgIterator Pkg = Ver.ParentPkg();
       pkgCache::PkgIterator Pkg = Ver.ParentPkg();
 
 
-      Fix->Clear(Pkg);
-      Fix->Protect(Pkg);
-      Fix->Remove(Pkg);
+      if (Fix != NULL)
+      {
+	 Fix->Clear(Pkg);
+	 Fix->Protect(Pkg);
+	 Fix->Remove(Pkg);
+      }
 
 
       if ((Pkg->CurrentVer == 0 && PurgePkgs == false) ||
       if ((Pkg->CurrentVer == 0 && PurgePkgs == false) ||
 	  (PurgePkgs == true && Pkg->CurrentState == pkgCache::State::NotInstalled))
 	  (PurgePkgs == true && Pkg->CurrentState == pkgCache::State::NotInstalled))
@@ -1385,10 +1390,10 @@ bool TryToInstallBuildDep(pkgCache::PkgIterator Pkg,pkgCacheFile &Cache,
 
 
    if (Remove == true)
    if (Remove == true)
    {
    {
-      TryToRemove RemoveAction(Cache, Fix);
+      TryToRemove RemoveAction(Cache, &Fix);
       RemoveAction(Pkg.VersionList());
       RemoveAction(Pkg.VersionList());
    } else if (Cache[Pkg].CandidateVer != 0) {
    } else if (Cache[Pkg].CandidateVer != 0) {
-      TryToInstall InstallAction(Cache, Fix, BrokenFix);
+      TryToInstall InstallAction(Cache, &Fix, BrokenFix);
       InstallAction(Cache[Pkg].CandidateVerIter(Cache));
       InstallAction(Cache[Pkg].CandidateVerIter(Cache));
       InstallAction.doAutoInstall();
       InstallAction.doAutoInstall();
    } else
    } else
@@ -1791,8 +1796,10 @@ bool DoInstall(CommandLine &CmdL)
    bool BrokenFix = false;
    bool BrokenFix = false;
    if (Cache->BrokenCount() != 0)
    if (Cache->BrokenCount() != 0)
       BrokenFix = true;
       BrokenFix = true;
-   
-   pkgProblemResolver Fix(Cache);
+
+   pkgProblemResolver* Fix = NULL;
+   if (_config->FindB("APT::Get::CallResolver", true) == true)
+      Fix = new pkgProblemResolver(Cache);
 
 
    static const unsigned short MOD_REMOVE = 1;
    static const unsigned short MOD_REMOVE = 1;
    static const unsigned short MOD_INSTALL = 2;
    static const unsigned short MOD_INSTALL = 2;
@@ -1823,6 +1830,8 @@ bool DoInstall(CommandLine &CmdL)
    if (_error->PendingError() == true)
    if (_error->PendingError() == true)
    {
    {
       helper.showVirtualPackageErrors(Cache);
       helper.showVirtualPackageErrors(Cache);
+      if (Fix != NULL)
+	 delete Fix;
       return false;
       return false;
    }
    }
 
 
@@ -1837,17 +1846,29 @@ bool DoInstall(CommandLine &CmdL)
 
 
       for (unsigned short i = 0; order[i] != 0; ++i)
       for (unsigned short i = 0; order[i] != 0; ++i)
       {
       {
-	 if (order[i] == MOD_INSTALL) {
+	 if (order[i] == MOD_INSTALL)
 	    InstallAction = std::for_each(verset[MOD_INSTALL].begin(), verset[MOD_INSTALL].end(), InstallAction);
 	    InstallAction = std::for_each(verset[MOD_INSTALL].begin(), verset[MOD_INSTALL].end(), InstallAction);
+	 else if (order[i] == MOD_REMOVE)
+	    RemoveAction = std::for_each(verset[MOD_REMOVE].begin(), verset[MOD_REMOVE].end(), RemoveAction);
+      }
+
+      if (Fix != NULL && _config->FindB("APT::Get::AutoSolving", true) == true)
+      {
+         for (unsigned short i = 0; order[i] != 0; ++i)
+         {
+	    if (order[i] != MOD_INSTALL)
+	       continue;
 	    InstallAction.propergateReleaseCandiateSwitching(helper.selectedByRelease, c0out);
 	    InstallAction.propergateReleaseCandiateSwitching(helper.selectedByRelease, c0out);
 	    InstallAction.doAutoInstall();
 	    InstallAction.doAutoInstall();
 	 }
 	 }
-	 else if (order[i] == MOD_REMOVE)
-	    RemoveAction = std::for_each(verset[MOD_REMOVE].begin(), verset[MOD_REMOVE].end(), RemoveAction);
       }
       }
 
 
       if (_error->PendingError() == true)
       if (_error->PendingError() == true)
+      {
+	 if (Fix != NULL)
+	    delete Fix;
 	 return false;
 	 return false;
+      }
 
 
       /* If we are in the Broken fixing mode we do not attempt to fix the
       /* If we are in the Broken fixing mode we do not attempt to fix the
 	 problems. This is if the user invoked install without -f and gave
 	 problems. This is if the user invoked install without -f and gave
@@ -1856,14 +1877,19 @@ bool DoInstall(CommandLine &CmdL)
       {
       {
 	 c1out << _("You might want to run 'apt-get -f install' to correct these:") << endl;
 	 c1out << _("You might want to run 'apt-get -f install' to correct these:") << endl;
 	 ShowBroken(c1out,Cache,false);
 	 ShowBroken(c1out,Cache,false);
-
+	 if (Fix != NULL)
+	    delete Fix;
 	 return _error->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution)."));
 	 return _error->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution)."));
       }
       }
-   
-      // Call the scored problem resolver
-      Fix.InstallProtect();
-      if (Fix.Resolve(true) == false)
-	 _error->Discard();
+
+      if (Fix != NULL)
+      {
+	 // Call the scored problem resolver
+	 Fix->InstallProtect();
+	 if (Fix->Resolve(true) == false)
+	    _error->Discard();
+	 delete Fix;
+      }
 
 
       // Now we check the state of the packages,
       // Now we check the state of the packages,
       if (Cache->BrokenCount() != 0)
       if (Cache->BrokenCount() != 0)
@@ -3278,7 +3304,10 @@ int main(int argc,const char *argv[])					/*{{{*/
    }
    }
 
 
    // simulate user-friendly if apt-get has no root privileges
    // simulate user-friendly if apt-get has no root privileges
-   if (getuid() != 0 && _config->FindB("APT::Get::Simulate") == true)
+   if (getuid() != 0 && _config->FindB("APT::Get::Simulate") == true &&
+	(CmdL.FileSize() == 0 ||
+	 (strcmp(CmdL.FileList[0], "source") != 0 && strcmp(CmdL.FileList[0], "download") != 0 &&
+	  strcmp(CmdL.FileList[0], "changelog") != 0)))
    {
    {
       if (_config->FindB("APT::Get::Show-User-Simulation-Note",true) == true)
       if (_config->FindB("APT::Get::Show-User-Simulation-Note",true) == true)
 	 cout << _("NOTE: This is only a simulation!\n"
 	 cout << _("NOTE: This is only a simulation!\n"

+ 1 - 0
debian/apt.conf.autoremove

@@ -9,6 +9,7 @@ APT
 	"^linux-restricted-modules.*";
 	"^linux-restricted-modules.*";
 	"^linux-ubuntu-modules-.*";
 	"^linux-ubuntu-modules-.*";
 	"^gnumach$";
 	"^gnumach$";
+	"^gnumach-image.*";
   };
   };
 
 
   Never-MarkAuto-Sections
   Never-MarkAuto-Sections

+ 37 - 1
debian/changelog

@@ -1,4 +1,4 @@
-apt (0.8.13.2) unstable; urgency=low
+apt (0.8.13.3) unstable; urgency=low
 
 
   [ Thorsten Spindler ]
   [ Thorsten Spindler ]
   * debian/zzapt.cron.daily:
   * debian/zzapt.cron.daily:
@@ -10,6 +10,42 @@ apt (0.8.13.2) unstable; urgency=low
 
 
  -- Michael Vogt <michael.vogt@ubuntu.com>  Thu, 10 Mar 2011 15:56:54 +0100
  -- Michael Vogt <michael.vogt@ubuntu.com>  Thu, 10 Mar 2011 15:56:54 +0100
 
 
+apt (0.8.13.2) unstable; urgency=low
+
+  [ David Kalnischkies ]
+  * apt-pkg/deb/dpkgpm.cc:
+    - skip --configure if all packages disappeared
+  * apt-pkg/vendor.cc, apt-pkg/vendorlist.cc:
+    - mark them as deprecated as they are unused
+  * apt-pkg/deb/deblistparser.h:
+    - enable StripMultiArch by default for ParseDepends
+  * debian/apt.conf.autoremove:
+    - adapt to new gnumach kernel package naming (Closes: #619337)
+  * doc/apt_preferences.5.xml:
+    - correct typo spotted by Charles Plessy (Closes: #619088)
+    - document ButAutomaticUpgrades together with NotAutomatic
+      as suggested by Charles Plessy (Closes: #619083)
+  * apt-pkg/depcache.cc:
+    - remove pseudo handling leftover from SetReInstall
+    - do not change protected packages in autoinstall (Closes: #618848)
+  * apt-pkg/pkgcachegen.cc:
+    - make "all"->"native" an implementation detail of NewPackage
+      rather than rewrite it in higher methods
+  * apt-pkg/cacheiterator.h:
+    - return "all" instead of native architecture without breaking the abi
+      (too much) by extending enum instead of using bitflags (LP: #733741)
+  * apt-pkg/aptconfiguration.cc:
+    - use dpkg --print-foreign-architectures to get multiarch configuration
+      if non is specified with APT::Architectures (Closes: #612958)
+  * cmdline/apt-get.cc:
+    - do not show simulation notice for non-root commands (Closes: #619072)
+    - be able to disable resolver with APT::Get::CallResolver and disable
+      auto installation with APT::Get::AutoSolving
+  * apt-pkg/deb/deblistparser.cc:
+    - create foo:any provides for all architectures for an allowed package
+
+ -- Michael Vogt <mvo@debian.org>  Tue, 05 Apr 2011 09:40:28 +0200
+
 apt (0.8.13.1) unstable; urgency=low
 apt (0.8.13.1) unstable; urgency=low
 
 
   * apt-pkg/acquire-item.cc: Use stat buffer if stat was
   * apt-pkg/acquire-item.cc: Use stat buffer if stat was

+ 9 - 4
doc/apt_preferences.5.xml

@@ -105,12 +105,16 @@ algorithm to set the priorities of the versions of a package.  Assign:
 <varlistentry>
 <varlistentry>
 <term>priority 1</term>
 <term>priority 1</term>
 <listitem><simpara>to the versions coming from archives which in their <filename>Release</filename>
 <listitem><simpara>to the versions coming from archives which in their <filename>Release</filename>
-files are marked as "NotAutomatic: yes" like the debian experimental archive.</simpara></listitem>
+files are marked as "NotAutomatic: yes" but <emphasis>not</emphasis> as "ButAutomaticUpgrades: yes"
+like the debian <literal>experimental</literal> archive.</simpara></listitem>
 </varlistentry>
 </varlistentry>
 
 
 <varlistentry>
 <varlistentry>
 <term>priority 100</term>
 <term>priority 100</term>
-<listitem><simpara>to the version that is already installed (if any).</simpara></listitem>
+<listitem><simpara>to the version that is already installed (if any) and to the versions coming
+from archives which in their <filename>Release</filename> files are marked as "NotAutomatic: yes" and
+"ButAutomaticUpgrades: yes" like the debian backports archive since <literal>squeeze-backports</literal>.
+</simpara></listitem>
 </varlistentry>
 </varlistentry>
 
 
 <varlistentry>
 <varlistentry>
@@ -127,9 +131,10 @@ files are marked as "NotAutomatic: yes" like the debian experimental archive.</s
 
 
 <para>If the target release has not been specified then APT simply assigns
 <para>If the target release has not been specified then APT simply assigns
 priority 100 to all installed package versions and priority 500 to all
 priority 100 to all installed package versions and priority 500 to all
-uninstalled package versions, expect versions coming from archives which
+uninstalled package versions, except versions coming from archives which
 in their <filename>Release</filename> files are marked as "NotAutomatic: yes" -
 in their <filename>Release</filename> files are marked as "NotAutomatic: yes" -
-these versions get the priority 1.</para>
+these versions get the priority 1 or priority 100 if it is additionally marked
+as "ButAutomaticUpgrades: yes".</para>
 
 
 <para>APT then applies the following rules, listed in order of precedence,
 <para>APT then applies the following rules, listed in order of precedence,
 to determine which version of a package to install.
 to determine which version of a package to install.

+ 36 - 9
test/integration/framework

@@ -261,18 +261,22 @@ Package: $NAME" > ${BUILDDIR}/debian/control
 	fi
 	fi
 	echo '3.0 (native)' > ${BUILDDIR}/debian/source/format
 	echo '3.0 (native)' > ${BUILDDIR}/debian/source/format
 	local SRCS="$( (cd ${BUILDDIR}/..; dpkg-source -b ${NAME}-${VERSION} 2>&1) | grep '^dpkg-source: info: building' | grep -o '[a-z0-9._+~-]*$')"
 	local SRCS="$( (cd ${BUILDDIR}/..; dpkg-source -b ${NAME}-${VERSION} 2>&1) | grep '^dpkg-source: info: building' | grep -o '[a-z0-9._+~-]*$')"
-
-	mkdir -p ${BUILDDIR}/debian/tmp/DEBIAN ${BUILDDIR}/debian/tmp/usr/share/doc/${NAME} ${BUILDDIR}/debian/tmp/usr/bin
-	cp ${BUILDDIR}/debian/copyright ${BUILDDIR}/debian/changelog ${BUILDDIR}/FEATURES ${BUILDDIR}/debian/tmp/usr/share/doc/${NAME}
-	cp ${BUILDDIR}/${NAME} ${BUILDDIR}/debian/tmp/usr/bin
-	(cd ${BUILDDIR}; dpkg-gencontrol -DArchitecture=$ARCH)
-	(cd ${BUILDDIR}/debian/tmp; md5sum $(find usr/ -type f) > DEBIAN/md5sums)
-
-	dpkg-deb --build ${BUILDDIR}/debian/tmp ${BUILDDIR}/.. 2> /dev/null > /dev/null
-	echo "pool/${NAME}_${VERSION}_${ARCH}.deb" >> ${BUILDDIR}/../${RELEASE}.${DISTSECTION}.pkglist
 	for SRC in $SRCS; do
 	for SRC in $SRCS; do
 		echo "pool/${SRC}" >> ${BUILDDIR}/../${RELEASE}.${DISTSECTION}.srclist
 		echo "pool/${SRC}" >> ${BUILDDIR}/../${RELEASE}.${DISTSECTION}.srclist
 	done
 	done
+
+	for arch in $(echo "$ARCH" | sed -e 's#,#\n#g'); do
+		rm -rf ${BUILDDIR}/debian/tmp
+		mkdir -p ${BUILDDIR}/debian/tmp/DEBIAN ${BUILDDIR}/debian/tmp/usr/share/doc/${NAME} ${BUILDDIR}/debian/tmp/usr/bin
+		cp ${BUILDDIR}/debian/copyright ${BUILDDIR}/debian/changelog ${BUILDDIR}/FEATURES ${BUILDDIR}/debian/tmp/usr/share/doc/${NAME}
+		cp ${BUILDDIR}/${NAME} ${BUILDDIR}/debian/tmp/usr/bin/${NAME}-${arch}
+		(cd ${BUILDDIR}; dpkg-gencontrol -DArchitecture=$arch)
+		(cd ${BUILDDIR}/debian/tmp; md5sum $(find usr/ -type f) > DEBIAN/md5sums)
+
+		dpkg-deb --build ${BUILDDIR}/debian/tmp ${BUILDDIR}/.. 2> /dev/null > /dev/null
+		echo "pool/${NAME}_${VERSION}_${arch}.deb" >> ${BUILDDIR}/../${RELEASE}.${DISTSECTION}.pkglist
+	done
+
 	mkdir -p ${BUILDDIR}/../${NAME}_${VERSION}
 	mkdir -p ${BUILDDIR}/../${NAME}_${VERSION}
 	cp ${BUILDDIR}/debian/changelog ${BUILDDIR}/../${NAME}_${VERSION}/
 	cp ${BUILDDIR}/debian/changelog ${BUILDDIR}/../${NAME}_${VERSION}/
 	cp ${BUILDDIR}/debian/changelog ${BUILDDIR}/../${NAME}_${VERSION}.changelog
 	cp ${BUILDDIR}/debian/changelog ${BUILDDIR}/../${NAME}_${VERSION}.changelog
@@ -418,6 +422,29 @@ Filename: pool/main/${NAME}/${NAME}_${VERSION}_${ARCH}.deb" >> $FILE
 	done
 	done
 }
 }
 
 
+insertinstalledpackage() {
+	local NAME="$1"
+	local ARCH="$2"
+	local VERSION="$3"
+	local DEPENDENCIES="$4"
+	local FILE="rootdir/var/lib/dpkg/status"
+	echo "Package: $NAME
+Status: install ok installed
+Priority: optional
+Section: other
+Installed-Size: 42
+Maintainer: Joe Sixpack <joe@example.org>
+Architecture: $ARCH
+Version: $VERSION" >> $FILE
+	test -z "$DEPENDENCIES" || echo "$DEPENDENCIES" >> $FILE
+	echo "Description: an autogenerated dummy ${NAME}=${VERSION}/${RELEASE}
+ If you find such a package installed on your system,
+ YOU did something horribly wrong! They are autogenerated
+ und used only by testcases for APT and surf no other propose…
+" >> $FILE
+}
+
+
 buildaptarchivefromincoming() {
 buildaptarchivefromincoming() {
 	msginfo "Build APT archive for ${CCMD}$(basename $0)${CINFO} based on incoming packages…"
 	msginfo "Build APT archive for ${CCMD}$(basename $0)${CINFO} based on incoming packages…"
 	cd aptarchive
 	cd aptarchive

+ 3 - 3
test/integration/test-bug-549968-install-depends-of-not-installed

@@ -17,10 +17,10 @@ setupaptarchive
 testequal 'Reading package lists...
 testequal 'Reading package lists...
 Building dependency tree...
 Building dependency tree...
   MarkInstall coolstuff [ i386 ] < none -> 1.0 > ( other ) FU=1
   MarkInstall coolstuff [ i386 ] < none -> 1.0 > ( other ) FU=1
-    Hold prevents MarkInstall of extracoolstuff [ i386 ] < none -> 1.0 > ( other ) FU=0
+    Ignore MarkInstall of extracoolstuff [ i386 ] < none -> 1.0 > ( other ) as its mode (Keep) is protected
 Package extracoolstuff is not installed, so not removed
 Package extracoolstuff is not installed, so not removed
 The following NEW packages will be installed:
 The following NEW packages will be installed:
   coolstuff
   coolstuff
 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
-Inst coolstuff (1.0 unstable [i386])
-Conf coolstuff (1.0 unstable [i386])' aptget install coolstuff extracoolstuff- -o Debug::pkgDepCache::Marker=1 -s
+Inst coolstuff (1.0 unstable [all])
+Conf coolstuff (1.0 unstable [all])' aptget install coolstuff extracoolstuff- -o Debug::pkgDepCache::Marker=1 -s

+ 4 - 4
test/integration/test-bug-590438-broken-provides-thanks-to-remove-order

@@ -62,13 +62,13 @@ predependsgawk2() {
 	echo "$pkgbasefile
 	echo "$pkgbasefile
 Pre-Depends: $1
 Pre-Depends: $1
 " >> rootdir/var/lib/dpkg/status
 " >> rootdir/var/lib/dpkg/status
-	testequalor2 "Inst coolstuff (1-1 localhost [i386])
-Conf coolstuff (1-1 localhost [i386])
+	testequalor2 "Inst coolstuff (1-1 localhost [all])
+Conf coolstuff (1-1 localhost [all])
 Inst gawk2 (1:3.1.7.dfsg-5 localhost [i386])
 Inst gawk2 (1:3.1.7.dfsg-5 localhost [i386])
 Conf gawk2 (1:3.1.7.dfsg-5 localhost [i386])
 Conf gawk2 (1:3.1.7.dfsg-5 localhost [i386])
-Remv mawk [1.3.3-15]" "Inst coolstuff (1-1 localhost [i386])
+Remv mawk [1.3.3-15]" "Inst coolstuff (1-1 localhost [all])
 Inst gawk2 (1:3.1.7.dfsg-5 localhost [i386])
 Inst gawk2 (1:3.1.7.dfsg-5 localhost [i386])
-Conf coolstuff (1-1 localhost [i386])
+Conf coolstuff (1-1 localhost [all])
 Conf gawk2 (1:3.1.7.dfsg-5 localhost [i386])
 Conf gawk2 (1:3.1.7.dfsg-5 localhost [i386])
 Remv mawk [1.3.3-15]" aptget install gawk2 mawk- -sqq -o PreDepends=$(echo "$1" | sed 's/ //g')
 Remv mawk [1.3.3-15]" aptget install gawk2 mawk- -sqq -o PreDepends=$(echo "$1" | sed 's/ //g')
 }
 }

+ 8 - 8
test/integration/test-bug-593360-modifiers-in-names

@@ -36,29 +36,29 @@ Building dependency tree...
 The following NEW packages will be installed:
 The following NEW packages will be installed:
   apt
   apt
 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
-Inst apt (0.8.8 localhost [i386])
-Conf apt (0.8.8 localhost [i386])' aptget install apt -s
+Inst apt (0.8.8 localhost [all])
+Conf apt (0.8.8 localhost [all])' aptget install apt -s
 
 
 testequal 'Reading package lists...
 testequal 'Reading package lists...
 Building dependency tree...
 Building dependency tree...
 The following NEW packages will be installed:
 The following NEW packages will be installed:
   apt+
   apt+
 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
-Inst apt+ (0.8.8 localhost [i386])
-Conf apt+ (0.8.8 localhost [i386])' aptget install apt+ -s
+Inst apt+ (0.8.8 localhost [all])
+Conf apt+ (0.8.8 localhost [all])' aptget install apt+ -s
 
 
 testequal 'Reading package lists...
 testequal 'Reading package lists...
 Building dependency tree...
 Building dependency tree...
 The following NEW packages will be installed:
 The following NEW packages will be installed:
   apt+
   apt+
 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
-Inst apt+ (0.8.8 localhost [i386])
-Conf apt+ (0.8.8 localhost [i386])' aptget install apt++ -s
+Inst apt+ (0.8.8 localhost [all])
+Conf apt+ (0.8.8 localhost [all])' aptget install apt++ -s
 
 
 testequal 'Reading package lists...
 testequal 'Reading package lists...
 Building dependency tree...
 Building dependency tree...
 The following NEW packages will be installed:
 The following NEW packages will be installed:
   apt+
   apt+
 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
-Inst apt+ (0.8.8 localhost [i386])
-Conf apt+ (0.8.8 localhost [i386])' aptget purge apt++ -s
+Inst apt+ (0.8.8 localhost [all])
+Conf apt+ (0.8.8 localhost [all])' aptget purge apt++ -s

+ 6 - 6
test/integration/test-bug-612099-multiarch-conflicts

@@ -67,9 +67,9 @@ The following NEW packages will be installed:
 The following packages will be upgraded:
 The following packages will be upgraded:
   libc6
   libc6
 1 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
 1 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
-Inst libc6 [1.0] (2.0 testing [i386])
+Inst libc6 [1.0] (2.0 testing [all])
 Inst foobar (1.0 stable [i386])
 Inst foobar (1.0 stable [i386])
-Conf libc6 (2.0 testing [i386])
+Conf libc6 (2.0 testing [all])
 Conf foobar (1.0 stable [i386])' aptget install foobar/stable libc6 -st testing
 Conf foobar (1.0 stable [i386])' aptget install foobar/stable libc6 -st testing
 
 
 testequal 'Reading package lists...
 testequal 'Reading package lists...
@@ -78,8 +78,8 @@ Reading state information...
 The following packages will be upgraded:
 The following packages will be upgraded:
   libc6
   libc6
 1 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
 1 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
-Inst libc6 [1.0] (2.0 testing [i386])
-Conf libc6 (2.0 testing [i386])' aptget upgrade -t testing -s
+Inst libc6 [1.0] (2.0 testing [all])
+Conf libc6 (2.0 testing [all])' aptget upgrade -t testing -s
 aptget upgrade -y -qq 2>&1 > /dev/null
 aptget upgrade -y -qq 2>&1 > /dev/null
 testdpkginstalled libc6
 testdpkginstalled libc6
 
 
@@ -171,8 +171,8 @@ Reading state information...
 The following packages will be upgraded:
 The following packages will be upgraded:
   libc6-same
   libc6-same
 1 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
 1 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
-Inst libc6-same [1.0] (2.0 testing [i386])
-Conf libc6-same (2.0 testing [i386])' aptget upgrade -t testing -s
+Inst libc6-same [1.0] (2.0 testing [all])
+Conf libc6-same (2.0 testing [all])' aptget upgrade -t testing -s
 aptget upgrade -y -qq 2>&1 > /dev/null
 aptget upgrade -y -qq 2>&1 > /dev/null
 testdpkginstalled libc6-same
 testdpkginstalled libc6-same
 
 

+ 59 - 0
test/integration/test-bug-612958-use-dpkg-multiarch-config

@@ -0,0 +1,59 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+setupenvironment
+configarchitecture 'i386'
+setupaptarchive
+
+insertinstalledpackage 'libapt' 'i386' '1.0'
+insertinstalledpackage 'libapt' 'amd64' '1.0'
+insertinstalledpackage 'libapt' 'armel' '1.0'
+
+testpass() {
+	rm rootdir/var/cache/apt/*.bin
+	msgtest 'Test architecture handling' "$1 with $2"
+	aptcache show libapt:$2 2> /dev/null > /dev/null && msgpass || msgfail
+}
+
+testfail() {
+	rm rootdir/var/cache/apt/*.bin
+	msgtest 'Test architecture handling' "$1 with $2"
+	aptcache show libapt:$2 2> /dev/null > /dev/null && msgfail || msgpass
+}
+
+testpass 'no config' 'i386'
+testfail 'no config' 'amd64'
+testfail 'no config' 'armel'
+
+CONFFILE=rootdir/etc/apt/apt.conf.d/99multiarch
+echo '#clear APT::Architectures;' >> $CONFFILE
+echo 'APT::Architectures:: "i386";' >> $CONFFILE
+echo 'APT::Architectures:: "amd64";' >> $CONFFILE
+
+testpass 'apt config' 'i386'
+testpass 'apt config' 'amd64'
+testfail 'apt config' 'armel'
+
+echo 'APT::Architectures:: "armel";' >> $CONFFILE
+
+testpass 'apt config' 'armel'
+
+rm $CONFFILE
+
+echo '#clear APT::Architectures;' >> $CONFFILE
+echo 'Dir::Bin::dpkg "./dpkg-printer";' >> $CONFFILE
+
+echo '#! /bin/sh
+echo "amd64"' > ./dpkg-printer
+chmod +x ./dpkg-printer
+
+testpass 'dpkg config' 'i386'
+testpass 'dpkg config' 'amd64'
+testfail 'dpkg config' 'armel'
+
+echo '#! /bin/sh
+echo "amd64 armel"' > ./dpkg-printer
+
+testpass 'dpkg config' 'armel'

+ 32 - 0
test/integration/test-bug-618848-always-respect-user-requests

@@ -0,0 +1,32 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+setupenvironment
+configarchitecture 'i386'
+
+insertinstalledpackage 'libdb4.8' 'all' '1.0'
+insertinstalledpackage 'exim4' 'all' '1.0' 'Depends: exim4-daemon-light | exim4-daemon-heavy'
+insertinstalledpackage 'exim4-daemon-light' 'all' '1.0' 'Depends: libdb4.8'
+insertpackage 'unstable' 'exim4-daemon-heavy' 'all' '1.0' 'Depends: libdb4.8'
+
+setupaptarchive
+
+testequal 'Reading package lists...
+Building dependency tree...
+  MarkDelete libdb4.8 [ i386 ] < 1.0 > ( other ) FU=1
+  MarkDelete exim4-daemon-light [ i386 ] < 1.0 > ( other ) FU=1
+    MarkInstall exim4-daemon-heavy [ i386 ] < none -> 1.0 > ( other ) FU=0
+      Ignore MarkInstall of libdb4.8 [ i386 ] < 1.0 > ( other ) as its mode (Delete) is protected
+    MarkDelete exim4-daemon-heavy [ i386 ] < none -> 1.0 > ( other ) FU=0
+  MarkDelete exim4 [ i386 ] < 1.0 > ( other ) FU=1
+The following packages will be REMOVED:
+  exim4 exim4-daemon-light libdb4.8
+  MarkDelete exim4 [ i386 ] < 1.0 > ( other ) FU=1
+0 upgraded, 0 newly installed, 3 to remove and 0 not upgraded.
+Remv exim4 [1.0]
+  MarkDelete exim4-daemon-light [ i386 ] < 1.0 > ( other ) FU=1
+Remv exim4-daemon-light [1.0]
+  MarkDelete libdb4.8 [ i386 ] < 1.0 > ( other ) FU=1
+Remv libdb4.8 [1.0]' aptget remove libdb4.8 -s -o Debug::pkgDepCache::Marker=1

+ 15 - 15
test/integration/test-release-candidate-switching

@@ -95,7 +95,7 @@ E: Trivial Only specified but this is not a trivial operation." aptget install a
 testequal "Reading package lists...
 testequal "Reading package lists...
 Building dependency tree...
 Building dependency tree...
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok'
-Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-common' because of 'amarok'
+Selected version '2.3.2-2+exp' (experimental [all]) for 'amarok-common' because of 'amarok'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-utils' because of 'amarok'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-utils' because of 'amarok'
 The following extra packages will be installed:
 The following extra packages will be installed:
    amarok-common (2.3.2-2+exp)
    amarok-common (2.3.2-2+exp)
@@ -117,7 +117,7 @@ E: Trivial Only specified but this is not a trivial operation." aptget install a
 testequal "Reading package lists...
 testequal "Reading package lists...
 Building dependency tree...
 Building dependency tree...
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-null'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-null'
-Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-common' because of 'amarok-null'
+Selected version '2.3.2-2+exp' (experimental [all]) for 'amarok-common' because of 'amarok-null'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-utils' because of 'amarok-null'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-utils' because of 'amarok-null'
 The following extra packages will be installed:
 The following extra packages will be installed:
    amarok-common (2.3.2-2+exp)
    amarok-common (2.3.2-2+exp)
@@ -140,7 +140,7 @@ E: Trivial Only specified but this is not a trivial operation." aptget install a
 testequal "Reading package lists...
 testequal "Reading package lists...
 Building dependency tree...
 Building dependency tree...
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok'
-Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-common' because of 'amarok'
+Selected version '2.3.2-2+exp' (experimental [all]) for 'amarok-common' because of 'amarok'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-utils' because of 'amarok'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-utils' because of 'amarok'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-null'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-null'
 The following extra packages will be installed:
 The following extra packages will be installed:
@@ -170,7 +170,7 @@ Building dependency tree...
 Selected version '2.3.2-2+exp' (experimental2 [i386]) for 'amarok-less'
 Selected version '2.3.2-2+exp' (experimental2 [i386]) for 'amarok-less'
 Selected version '5:4.6.0+exp' (experimental [i386]) for 'phonon-backend-xine' because of 'amarok-less'
 Selected version '5:4.6.0+exp' (experimental [i386]) for 'phonon-backend-xine' because of 'amarok-less'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-higher'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-higher'
-Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-common' because of 'amarok-higher'
+Selected version '2.3.2-2+exp' (experimental [all]) for 'amarok-common' because of 'amarok-higher'
 Selected version '5:4.6.0+exp' (experimental [i386]) for 'phonon-backend-xine' because of 'amarok-higher'
 Selected version '5:4.6.0+exp' (experimental [i386]) for 'phonon-backend-xine' because of 'amarok-higher'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-utils' because of 'amarok-higher'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-utils' because of 'amarok-higher'
 The following extra packages will be installed:
 The following extra packages will be installed:
@@ -195,7 +195,7 @@ E: Trivial Only specified but this is not a trivial operation." aptget install a
 testequal "Reading package lists...
 testequal "Reading package lists...
 Building dependency tree...
 Building dependency tree...
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-null2'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-null2'
-Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-common' because of 'amarok-null2'
+Selected version '2.3.2-2+exp' (experimental [all]) for 'amarok-common' because of 'amarok-null2'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-utils' because of 'amarok-null2'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-utils' because of 'amarok-null2'
 The following extra packages will be installed:
 The following extra packages will be installed:
    amarok-common (2.3.2-2+exp)
    amarok-common (2.3.2-2+exp)
@@ -218,7 +218,7 @@ E: Trivial Only specified but this is not a trivial operation." aptget install a
 testequal "Reading package lists...
 testequal "Reading package lists...
 Building dependency tree...
 Building dependency tree...
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-xine'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-xine'
-Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-common' because of 'amarok-xine'
+Selected version '2.3.2-2+exp' (experimental [all]) for 'amarok-common' because of 'amarok-xine'
 Selected version '5:4.6.0+exp' (experimental [i386]) for 'phonon-backend-xine' because of 'amarok-xine'
 Selected version '5:4.6.0+exp' (experimental [i386]) for 'phonon-backend-xine' because of 'amarok-xine'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-utils' because of 'amarok-xine'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-utils' because of 'amarok-xine'
 The following extra packages will be installed:
 The following extra packages will be installed:
@@ -242,7 +242,7 @@ E: Trivial Only specified but this is not a trivial operation." aptget install a
 testequal "Reading package lists...
 testequal "Reading package lists...
 Building dependency tree...
 Building dependency tree...
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-xine2'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-xine2'
-Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-common' because of 'amarok-xine2'
+Selected version '2.3.2-2+exp' (experimental [all]) for 'amarok-common' because of 'amarok-xine2'
 Selected version '5:4.20.0+exp' (experimental [i386]) for 'phonon-backend-null' because of 'amarok-xine2'
 Selected version '5:4.20.0+exp' (experimental [i386]) for 'phonon-backend-null' because of 'amarok-xine2'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-utils' because of 'amarok-xine2'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-utils' because of 'amarok-xine2'
 The following extra packages will be installed:
 The following extra packages will be installed:
@@ -266,9 +266,9 @@ E: Trivial Only specified but this is not a trivial operation." aptget install a
 testequal "Reading package lists...
 testequal "Reading package lists...
 Building dependency tree...
 Building dependency tree...
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-xine3'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-xine3'
-Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-common' because of 'amarok-xine3'
+Selected version '2.3.2-2+exp' (experimental [all]) for 'amarok-common' because of 'amarok-xine3'
 Selected version '5:4.6.0+exp' (experimental [i386]) for 'phonon-backend-xine3' because of 'amarok-xine3'
 Selected version '5:4.6.0+exp' (experimental [i386]) for 'phonon-backend-xine3' because of 'amarok-xine3'
-Selected version '2.0' (experimental [i386]) for 'intermediatepkg' because of 'phonon-backend-xine3'
+Selected version '2.0' (experimental [all]) for 'intermediatepkg' because of 'phonon-backend-xine3'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-utils' because of 'amarok-xine3'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-utils' because of 'amarok-xine3'
 The following extra packages will be installed:
 The following extra packages will be installed:
    amarok-common (2.3.2-2+exp)
    amarok-common (2.3.2-2+exp)
@@ -293,7 +293,7 @@ E: Trivial Only specified but this is not a trivial operation." aptget install a
 testequal "Reading package lists...
 testequal "Reading package lists...
 Building dependency tree...
 Building dependency tree...
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-xine4'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-xine4'
-Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-common' because of 'amarok-xine4'
+Selected version '2.3.2-2+exp' (experimental [all]) for 'amarok-common' because of 'amarok-xine4'
 Selected version '5:4.20.0+exp' (experimental [i386]) for 'phonon-backend-null' because of 'amarok-xine4'
 Selected version '5:4.20.0+exp' (experimental [i386]) for 'phonon-backend-null' because of 'amarok-xine4'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-utils' because of 'amarok-xine4'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-utils' because of 'amarok-xine4'
 The following extra packages will be installed:
 The following extra packages will be installed:
@@ -317,7 +317,7 @@ E: Trivial Only specified but this is not a trivial operation." aptget install a
 testequal "Reading package lists...
 testequal "Reading package lists...
 Building dependency tree...
 Building dependency tree...
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-broken'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-broken'
-Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-common' because of 'amarok-broken'
+Selected version '2.3.2-2+exp' (experimental [all]) for 'amarok-common' because of 'amarok-broken'
 Selected version '5:4.20.0+exp' (experimental [i386]) for 'phonon-backend-null' because of 'amarok-broken'
 Selected version '5:4.20.0+exp' (experimental [i386]) for 'phonon-backend-null' because of 'amarok-broken'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-utils' because of 'amarok-broken'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-utils' because of 'amarok-broken'
 The following extra packages will be installed:
 The following extra packages will be installed:
@@ -341,7 +341,7 @@ E: Trivial Only specified but this is not a trivial operation." aptget install a
 testequal "Reading package lists...
 testequal "Reading package lists...
 Building dependency tree...
 Building dependency tree...
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-recommends'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-recommends'
-Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-common' because of 'amarok-recommends'
+Selected version '2.3.2-2+exp' (experimental [all]) for 'amarok-common' because of 'amarok-recommends'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-utils' because of 'amarok-recommends'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-utils' because of 'amarok-recommends'
 The following extra packages will be installed:
 The following extra packages will be installed:
    amarok-common (2.3.2-2+exp)
    amarok-common (2.3.2-2+exp)
@@ -364,7 +364,7 @@ E: Trivial Only specified but this is not a trivial operation." aptget install a
 testequal "Reading package lists...
 testequal "Reading package lists...
 Building dependency tree...
 Building dependency tree...
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-recommends'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-recommends'
-Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-common' because of 'amarok-recommends'
+Selected version '2.3.2-2+exp' (experimental [all]) for 'amarok-common' because of 'amarok-recommends'
 The following extra packages will be installed:
 The following extra packages will be installed:
    amarok-common (2.3.2-2+exp)
    amarok-common (2.3.2-2+exp)
 Recommended packages:
 Recommended packages:
@@ -385,7 +385,7 @@ E: Trivial Only specified but this is not a trivial operation." aptget install a
 testequal "Reading package lists...
 testequal "Reading package lists...
 Building dependency tree...
 Building dependency tree...
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-recommends2'
 Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-recommends2'
-Selected version '2.3.2-2+exp' (experimental [i386]) for 'amarok-common' because of 'amarok-recommends2'
+Selected version '2.3.2-2+exp' (experimental [all]) for 'amarok-common' because of 'amarok-recommends2'
 The following extra packages will be installed:
 The following extra packages will be installed:
    amarok-common (2.3.2-2+exp)
    amarok-common (2.3.2-2+exp)
    libc6 (2.11.2-7+sid)
    libc6 (2.11.2-7+sid)
@@ -406,7 +406,7 @@ E: Trivial Only specified but this is not a trivial operation." aptget install a
 # if one depends doesn't work, we don't need to look deeper…
 # if one depends doesn't work, we don't need to look deeper…
 testequal "Reading package lists...
 testequal "Reading package lists...
 Building dependency tree...
 Building dependency tree...
-Selected version '1.0' (experimental [i386]) for 'uninstallablepkg'
+Selected version '1.0' (experimental [all]) for 'uninstallablepkg'
 Some packages could not be installed. This may mean that you have
 Some packages could not be installed. This may mean that you have
 requested an impossible situation or if you are using the unstable
 requested an impossible situation or if you are using the unstable
 distribution that some required packages have not yet been created
 distribution that some required packages have not yet been created