]> git.saurik.com Git - apt.git/commitdiff
merged from debian-experimental2
authorMichael Vogt <michael.vogt@ubuntu.com>
Tue, 13 Mar 2012 13:21:00 +0000 (14:21 +0100)
committerMichael Vogt <michael.vogt@ubuntu.com>
Tue, 13 Mar 2012 13:21:00 +0000 (14:21 +0100)
53 files changed:
apt-inst/dirstream.cc
apt-pkg/acquire-item.cc
apt-pkg/acquire.cc
apt-pkg/algorithms.cc
apt-pkg/aptconfiguration.cc
apt-pkg/cachefile.cc
apt-pkg/cachefilter.cc
apt-pkg/cacheset.h
apt-pkg/contrib/fileutl.cc
apt-pkg/contrib/fileutl.h
apt-pkg/contrib/strutl.cc
apt-pkg/deb/deblistparser.cc
apt-pkg/deb/debmetaindex.cc
apt-pkg/deb/dpkgpm.cc
apt-pkg/depcache.cc
apt-pkg/indexcopy.cc
apt-pkg/indexrecords.cc
apt-pkg/orderlist.cc
apt-pkg/packagemanager.cc
apt-pkg/pkgrecords.cc
apt-pkg/pkgsystem.cc
apt-pkg/sourcelist.cc
apt-pkg/srcrecords.cc
apt-pkg/tagfile.cc
apt-pkg/version.cc
cmdline/acqprogress.cc
cmdline/apt-cache.cc
cmdline/apt-cdrom.cc
cmdline/apt-extracttemplates.cc
cmdline/apt-get.cc
cmdline/apt-mark.cc
debian/changelog
ftparchive/cachedb.h
ftparchive/writer.cc
methods/ftp.cc
methods/http.cc
methods/http.h
methods/https.h
methods/mirror.cc
methods/rsh.cc
test/integration/Packages-bug-64141-install-dependencies-for-on-hold [deleted file]
test/integration/framework
test/integration/skip-avoid-avoiding-breaks-predepends [new file with mode: 0755]
test/integration/status-bug-64141-install-dependencies-for-on-hold [deleted file]
test/integration/test-bug-549968-install-depends-of-not-installed
test/integration/test-bug-612099-multiarch-conflicts
test/integration/test-bug-618288-multiarch-same-lockstep
test/integration/test-bug-624218-Translation-file-handling
test/integration/test-bug-64141-install-dependencies-for-on-hold
test/integration/test-conflicts-loop
test/integration/test-pin-non-existent-package
test/integration/test-releasefile-verification
test/integration/test-suggest-installed-multiarch-silbing [new file with mode: 0755]

index bb0bf96c18a480bdaa32727b73637224a85f2b92..65d1aa188a6b3080fa7e8c3177d53ff0e6c124ba 100644 (file)
@@ -46,15 +46,13 @@ bool pkgDirStream::DoItem(Item &Itm,int &Fd)
         // fchmod deals with umask and fchown sets the ownership
         if (fchmod(iFd,Itm.Mode) != 0)
         {
-           _error->Errno("fchmod",_("Failed to write file %s"), Itm.Name);
            close(iFd);
-           return false;
+           return _error->Errno("fchmod",_("Failed to write file %s"), Itm.Name);
         }
         if (fchown(iFd,Itm.UID,Itm.GID) != 0 && errno != EPERM)
         {
-           return _error->Errno("fchown",_("Failed to write file %s"), Itm.Name);
            close(iFd);
-           return false;
+           return _error->Errno("fchown",_("Failed to write file %s"), Itm.Name);
         }
         Fd = iFd;
         return true;
index f231c42b4219e7e0e871376fd98f9423934ba438..a30e98858adf645763408442fc185ade9a1413e7 100644 (file)
@@ -189,14 +189,14 @@ void pkgAcquire::Item::ReportMirrorFailure(string FailCode)
                                                                        /*}}}*/
 // AcqSubIndex::AcqSubIndex - Constructor                              /*{{{*/
 // ---------------------------------------------------------------------
-/* Get the Index file first and see if there are languages available
- * If so, create a pkgAcqIndexTrans for the found language(s).
- */
+/* Get a sub-index file based on checksums from a 'master' file and
+   possibly query additional files */
 pkgAcqSubIndex::pkgAcqSubIndex(pkgAcquire *Owner, string const &URI,
                                 string const &URIDesc, string const &ShortDesc,
                                 HashString const &ExpectedHash)
    : Item(Owner), ExpectedHash(ExpectedHash)
 {
+   /* XXX: Beware: Currently this class does nothing (of value) anymore ! */
    Debug = _config->FindB("Debug::pkgAcquire::SubIndex",false);
 
    DestFile = _config->FindDir("Dir::State::lists") + "partial/";
@@ -236,17 +236,7 @@ void pkgAcqSubIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)  /*{{{*
    Status = StatDone;
    Dequeue();
 
-   // No good Index is provided, so try guessing
-   std::vector<std::string> langs = APT::Configuration::getLanguages(true);
-   for (std::vector<std::string>::const_iterator l = langs.begin();
-       l != langs.end(); ++l)
-   {
-      if (*l == "none") continue;
-      string const file = "Translation-" + *l;
-      new pkgAcqIndexTrans(Owner, Desc.URI.substr(0, Desc.URI.rfind('/')+1).append(file),
-               Desc.Description.erase(Desc.Description.rfind(' ')+1).append(file),
-               file);
-   }
+   // No good Index is provided
 }
                                                                        /*}}}*/
 void pkgAcqSubIndex::Done(string Message,unsigned long long Size,string Md5Hash,       /*{{{*/
@@ -305,38 +295,7 @@ bool pkgAcqSubIndex::ParseIndex(string const &IndexFile)           /*{{{*/
    indexRecords SubIndexParser;
    if (FileExists(IndexFile) == false || SubIndexParser.Load(IndexFile) == false)
       return false;
-
-   std::vector<std::string> lang = APT::Configuration::getLanguages(true);
-   for (std::vector<std::string>::const_iterator l = lang.begin();
-       l != lang.end(); ++l)
-   {
-      if (*l == "none")
-        continue;
-
-      string file = "Translation-" + *l;
-      indexRecords::checkSum const *Record = SubIndexParser.Lookup(file);
-      HashString expected;
-      if (Record == NULL)
-      {
-        // FIXME: the Index file provided by debian currently only includes bz2 records
-        Record = SubIndexParser.Lookup(file + ".bz2");
-        if (Record == NULL)
-           continue;
-      }
-      else
-      {
-        expected = Record->Hash;
-        if (expected.empty() == true)
-           continue;
-      }
-
-      IndexTarget target;
-      target.Description = Desc.Description.erase(Desc.Description.rfind(' ')+1).append(file);
-      target.MetaKey = file;
-      target.ShortDesc = file;
-      target.URI = Desc.URI.substr(0, Desc.URI.rfind('/')+1).append(file);
-      new pkgAcqIndexTrans(Owner, &target, expected, &SubIndexParser);
-   }
+   // so something with the downloaded index
    return true;
 }
                                                                        /*}}}*/
@@ -1385,6 +1344,18 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify)                          /*{{{*/
       return;
    }
 #endif
+   bool transInRelease = false;
+   {
+      std::vector<std::string> const keys = MetaIndexParser->MetaKeys();
+      for (std::vector<std::string>::const_iterator k = keys.begin(); k != keys.end(); ++k)
+        // FIXME: Feels wrong to check for hardcoded string here, but what should we do else…
+        if (k->find("Translation-") != std::string::npos)
+        {
+           transInRelease = true;
+           break;
+        }
+   }
+
    for (vector <struct IndexTarget*>::const_iterator Target = IndexTargets->begin();
         Target != IndexTargets->end();
         ++Target)
@@ -1422,8 +1393,15 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify)                          /*{{{*/
         if ((*Target)->IsSubIndex() == true)
            new pkgAcqSubIndex(Owner, (*Target)->URI, (*Target)->Description,
                                (*Target)->ShortDesc, ExpectedIndexHash);
-        else
-           new pkgAcqIndexTrans(Owner, *Target, ExpectedIndexHash, MetaIndexParser);
+        else if (transInRelease == false || MetaIndexParser->Exists((*Target)->MetaKey) == true)
+        {
+           if (_config->FindB("Acquire::PDiffs",true) == true && transInRelease == true &&
+               MetaIndexParser->Exists(string((*Target)->MetaKey).append(".diff/Index")) == true)
+              new pkgAcqDiffIndex(Owner, (*Target)->URI, (*Target)->Description,
+                                  (*Target)->ShortDesc, ExpectedIndexHash);
+           else
+              new pkgAcqIndexTrans(Owner, *Target, ExpectedIndexHash, MetaIndexParser);
+        }
         continue;
       }
 
@@ -1620,6 +1598,13 @@ void pkgAcqMetaClearSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*
 {
    if (AuthPass == false)
    {
+      // Remove the 'old' InRelease file if we try Release.gpg now as otherwise
+      // the file will stay around and gives a false-auth impression (CVE-2012-0214)
+      string FinalFile = _config->FindDir("Dir::State::lists");
+      FinalFile.append(URItoFileName(RealURI));
+      if (FileExists(FinalFile))
+        unlink(FinalFile.c_str());
+
       new pkgAcqMetaSig(Owner,
                        MetaSigURI, MetaSigURIDesc, MetaSigShortDesc,
                        MetaIndexURI, MetaIndexURIDesc, MetaIndexShortDesc,
@@ -1825,7 +1810,18 @@ bool pkgAcqArchive::QueueNext()
         else
            PartialSize = Buf.st_size;
       }
-      
+
+      // Disables download of archives - useful if no real installation follows,
+      // e.g. if we are just interested in proposed installation order
+      if (_config->FindB("Debug::pkgAcqArchive::NoQueue", false) == true)
+      {
+        Complete = true;
+        Local = true;
+        Status = StatDone;
+        StoreFilename = DestFile = FinalFile;
+        return true;
+      }
+
       // Create the item
       Local = false;
       Desc.URI = Index->ArchiveURI(PkgFile);
index cdc3fba4b8059994fa3251953d159a102830569b..573a85c2fafc0aeea5b62ef619bee50ec4ce9c2d 100644 (file)
@@ -766,7 +766,7 @@ void pkgAcquire::Queue::Bump()
 // AcquireStatus::pkgAcquireStatus - Constructor                       /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-pkgAcquireStatus::pkgAcquireStatus() : Update(true), MorePulses(false)
+pkgAcquireStatus::pkgAcquireStatus() : d(NULL), Update(true), MorePulses(false)
 {
    Start();
 }
index c337ace877374e6dd0c6afcde9d60a66d22bf5d1..8beb2d51c1ccd4aaa2bc2a8bf563dfa5e464c3e5 100644 (file)
@@ -471,7 +471,7 @@ bool pkgMinimizeUpgrade(pkgDepCache &Cache)
 // ProblemResolver::pkgProblemResolver - Constructor                   /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-pkgProblemResolver::pkgProblemResolver(pkgDepCache *pCache) : Cache(*pCache)
+pkgProblemResolver::pkgProblemResolver(pkgDepCache *pCache) : d(NULL), Cache(*pCache)
 {
    // Allocate memory
    unsigned long Size = Cache.Head().PackageCount;
@@ -556,7 +556,8 @@ void pkgProblemResolver::MakeScores()
          essantial package above most other packages but low enough
         to allow an obsolete essential packages to be removed by
         a conflicts on a powerfull normal package (ie libc6) */
-      if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
+      if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential
+         || (I->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important)
         Score += PrioEssentials;
 
       // We transform the priority
@@ -631,7 +632,8 @@ void pkgProblemResolver::MakeScores()
    {
       if ((Flags[I->ID] & Protected) != 0)
         Scores[I->ID] += AddProtected;
-      if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
+      if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential ||
+          (I->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important)
         Scores[I->ID] += AddEssential;
    }
 }
@@ -1430,6 +1432,13 @@ static int PrioComp(const void *A,const void *B)
    if ((L.ParentPkg()->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential &&
        (R.ParentPkg()->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
      return -1;
+
+   if ((L.ParentPkg()->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important &&
+       (R.ParentPkg()->Flags & pkgCache::Flag::Important) != pkgCache::Flag::Important)
+     return 1;
+   if ((L.ParentPkg()->Flags & pkgCache::Flag::Important) != pkgCache::Flag::Important &&
+       (R.ParentPkg()->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important)
+     return -1;
    
    if (L->Priority != R->Priority)
       return R->Priority - L->Priority;
index b5ad74831d5c41918e8314e43b765a878a8c5635..4324f0e6395e60fcba7d728658bc9931862d1156 100644 (file)
@@ -376,7 +376,7 @@ std::vector<std::string> const Configuration::getArchitectures(bool const &Cache
                        dup2(nullfd, STDIN_FILENO);
                        dup2(external[1], STDOUT_FILENO);
                        dup2(nullfd, STDERR_FILENO);
-                       execv(Args[0], (char**) &Args[0]);
+                       execvp(Args[0], (char**) &Args[0]);
                        _error->WarningE("getArchitecture", "Can't detect foreign architectures supported by dpkg!");
                        _exit(100);
                }
@@ -392,7 +392,9 @@ std::vector<std::string> const Configuration::getArchitectures(bool const &Cache
                                        if (arch[0] != '\0') {
                                                char const* archend = arch;
                                                for (; isspace(*archend) == 0 && *archend != '\0'; ++archend);
-                                               archs.push_back(string(arch, (archend - arch)));
+                                               string a(arch, (archend - arch));
+                                               if (std::find(archs.begin(), archs.end(), a) == archs.end())
+                                                       archs.push_back(a);
                                        }
                                        arch = strtok(NULL, " ");
                                }
index 1b8d91a44951b31c37c1d9fcb112c8c77af437b9..7c2276185cbfcd8dc502791ebb41ddac499902d1 100644 (file)
@@ -30,7 +30,7 @@
 // CacheFile::CacheFile - Constructor                                  /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-pkgCacheFile::pkgCacheFile() : Map(NULL), Cache(NULL), DCache(NULL),
+pkgCacheFile::pkgCacheFile() : d(NULL), Map(NULL), Cache(NULL), DCache(NULL),
                                SrcList(NULL), Policy(NULL)
 {
 }
@@ -178,6 +178,40 @@ void pkgCacheFile::RemoveCaches()
       unlink(pkgcache.c_str());
    if (srcpkgcache.empty() == false && RealFileExists(srcpkgcache) == true)
       unlink(srcpkgcache.c_str());
+   if (pkgcache.empty() == false)
+   {
+      std::string cachedir = flNotFile(pkgcache);
+      std::string cachefile = flNotDir(pkgcache);
+      if (cachedir.empty() != true && cachefile.empty() != true && DirectoryExists(cachedir) == true)
+      {
+        cachefile.append(".");
+        std::vector<std::string> caches = GetListOfFilesInDir(cachedir, false);
+        for (std::vector<std::string>::const_iterator file = caches.begin(); file != caches.end(); ++file)
+        {
+           std::string nuke = flNotDir(*file);
+           if (strncmp(cachefile.c_str(), nuke.c_str(), cachefile.length()) != 0)
+              continue;
+           unlink(file->c_str());
+        }
+      }
+   }
+
+   if (srcpkgcache.empty() == true)
+      return;
+
+   std::string cachedir = flNotFile(srcpkgcache);
+   std::string cachefile = flNotDir(srcpkgcache);
+   if (cachedir.empty() == true || cachefile.empty() == true || DirectoryExists(cachedir) == false)
+      return;
+   cachefile.append(".");
+   std::vector<std::string> caches = GetListOfFilesInDir(cachedir, false);
+   for (std::vector<std::string>::const_iterator file = caches.begin(); file != caches.end(); ++file)
+   {
+      std::string nuke = flNotDir(*file);
+      if (strncmp(cachefile.c_str(), nuke.c_str(), cachefile.length()) != 0)
+        continue;
+      unlink(file->c_str());
+   }
 }
                                                                        /*}}}*/
 // CacheFile::Close - close the cache files                            /*{{{*/
index 210a9a9ab8f2eac5047500daabe5c31aedc55bf8..9ec3fa699ba34d9e45a645dab5bb3b88823724a6 100644 (file)
@@ -18,7 +18,7 @@
                                                                        /*}}}*/
 namespace APT {
 namespace CacheFilter {
-PackageNameMatchesRegEx::PackageNameMatchesRegEx(std::string const &Pattern) {/*{{{*/
+PackageNameMatchesRegEx::PackageNameMatchesRegEx(std::string const &Pattern) : d(NULL) {/*{{{*/
        pattern = new regex_t;
        int const Res = regcomp(pattern, Pattern.c_str(), REG_EXTENDED | REG_ICASE | REG_NOSUB);
        if (Res == 0)
index 91d7eec1cfb0311a8d412fe5e51c5497d163a58f..6f0a0e3584dc318f8520b81051a8b6de9c9bd058 100644 (file)
@@ -191,6 +191,8 @@ public:                                                                     /*{{{*/
                inline iterator operator++(int) { iterator tmp(*this); operator++(); return tmp; }
                inline bool operator!=(iterator const &i) const { return _iter != i._iter; };
                inline bool operator==(iterator const &i) const { return _iter == i._iter; };
+               inline iterator& operator=(iterator const &i) { _iter = i._iter; return *this; };
+               inline iterator& operator=(typename Container::iterator const &i) { _iter = i; return *this; };
                friend std::ostream& operator<<(std::ostream& out, iterator i) { return operator<<(out, *i); }
        };
                                                                        /*}}}*/
@@ -201,7 +203,9 @@ public:                                                                     /*{{{*/
 
        bool empty() const { return _cont.empty(); };
        void clear() { return _cont.clear(); };
+       //FIXME: on ABI break, replace the first with the second without bool
        void erase(iterator position) { _cont.erase((typename Container::iterator)position); };
+       iterator& erase(iterator &position, bool) { return position = _cont.erase((typename Container::iterator)position); };
        size_t erase(const pkgCache::PkgIterator x) { return _cont.erase(x); };
        void erase(iterator first, iterator last) { _cont.erase(first, last); };
        size_t size() const { return _cont.size(); };
@@ -507,6 +511,8 @@ public:                                                                     /*{{{*/
                inline iterator operator++(int) { iterator tmp(*this); operator++(); return tmp; }
                inline bool operator!=(iterator const &i) const { return _iter != i._iter; };
                inline bool operator==(iterator const &i) const { return _iter == i._iter; };
+               inline iterator& operator=(iterator const &i) { _iter = i._iter; return *this; };
+               inline iterator& operator=(typename Container::iterator const &i) { _iter = i; return *this; };
                friend std::ostream& operator<<(std::ostream& out, iterator i) { return operator<<(out, *i); }
        };
                                                                        /*}}}*/
@@ -516,7 +522,9 @@ public:                                                                     /*{{{*/
        void insert(const_iterator begin, const_iterator end) { _cont.insert(begin, end); };
        bool empty() const { return _cont.empty(); };
        void clear() { return _cont.clear(); };
+       //FIXME: on ABI break, replace the first with the second without bool
        void erase(iterator position) { _cont.erase((typename Container::iterator)position); };
+       iterator& erase(iterator &position, bool) { return position = _cont.erase((typename Container::iterator)position); };
        size_t erase(const pkgCache::VerIterator x) { return _cont.erase(x); };
        void erase(iterator first, iterator last) { _cont.erase(first, last); };
        size_t size() const { return _cont.size(); };
index 28898fc34820834aaf6f76900021f6a680e657ba..1808489d7d276cc47c23afdde3589e0301c3fed8 100644 (file)
@@ -387,6 +387,13 @@ std::vector<string> GetListOfFilesInDir(string const &Dir, std::vector<string> c
       {
         if (RealFileExists(File.c_str()) == false)
         {
+           // do not show ignoration warnings for directories
+           if (
+#ifdef _DIRENT_HAVE_D_TYPE
+               Ent->d_type == DT_DIR ||
+#endif
+               DirectoryExists(File.c_str()) == true)
+              continue;
            if (SilentIgnore.Match(Ent->d_name) == false)
               _error->Notice(_("Ignoring '%s' in directory '%s' as it is not a regular file"), Ent->d_name, Dir.c_str());
            continue;
@@ -454,6 +461,80 @@ std::vector<string> GetListOfFilesInDir(string const &Dir, std::vector<string> c
    }
    closedir(D);
 
+   if (SortList == true)
+      std::sort(List.begin(),List.end());
+   return List;
+}
+std::vector<string> GetListOfFilesInDir(string const &Dir, bool SortList)
+{
+   bool const Debug = _config->FindB("Debug::GetListOfFilesInDir", false);
+   if (Debug == true)
+      std::clog << "Accept in " << Dir << " all regular files" << std::endl;
+
+   std::vector<string> List;
+
+   if (DirectoryExists(Dir.c_str()) == false)
+   {
+      _error->Error(_("List of files can't be created as '%s' is not a directory"), Dir.c_str());
+      return List;
+   }
+
+   DIR *D = opendir(Dir.c_str());
+   if (D == 0)
+   {
+      _error->Errno("opendir",_("Unable to read %s"),Dir.c_str());
+      return List;
+   }
+
+   for (struct dirent *Ent = readdir(D); Ent != 0; Ent = readdir(D)) 
+   {
+      // skip "hidden" files
+      if (Ent->d_name[0] == '.')
+        continue;
+
+      // Make sure it is a file and not something else
+      string const File = flCombine(Dir,Ent->d_name);
+#ifdef _DIRENT_HAVE_D_TYPE
+      if (Ent->d_type != DT_REG)
+#endif
+      {
+        if (RealFileExists(File.c_str()) == false)
+        {
+           if (Debug == true)
+              std::clog << "Bad file: " << Ent->d_name << " → it is not a real file" << std::endl;
+           continue;
+        }
+      }
+
+      // Skip bad filenames ala run-parts
+      const char *C = Ent->d_name;
+      for (; *C != 0; ++C)
+        if (isalpha(*C) == 0 && isdigit(*C) == 0
+            && *C != '_' && *C != '-' && *C != '.')
+           break;
+
+      // we don't reach the end of the name -> bad character included
+      if (*C != 0)
+      {
+        if (Debug == true)
+           std::clog << "Bad file: " << Ent->d_name << " → bad character »" << *C << "« in filename" << std::endl;
+        continue;
+      }
+
+      // skip filenames which end with a period. These are never valid
+      if (*(C - 1) == '.')
+      {
+        if (Debug == true)
+           std::clog << "Bad file: " << Ent->d_name << " → Period as last character" << std::endl;
+        continue;
+      }
+
+      if (Debug == true)
+        std::clog << "Accept file: " << Ent->d_name << " in " << Dir << std::endl;
+      List.push_back(File);
+   }
+   closedir(D);
+
    if (SortList == true)
       std::sort(List.begin(),List.end());
    return List;
@@ -890,6 +971,11 @@ bool FileFd::OpenDescriptor(int Fd, unsigned int const Mode, CompressMode Compre
    std::vector<APT::Configuration::Compressor> const compressors = APT::Configuration::getCompressors();
    std::vector<APT::Configuration::Compressor>::const_iterator compressor = compressors.begin();
    std::string name;
+
+   // compat with the old API
+   if (Mode == ReadOnlyGzip && Compress == None)
+      Compress = Gzip;
+
    switch (Compress)
    {
    case None: name = "."; break;
index 8a50251421625ba030b76f34201fa71905011fe8..1ca41cb7d66c6b21cc3950613e30f696f4e6357b 100644 (file)
@@ -108,10 +108,7 @@ class FileFd
    bool OpenDescriptor(int Fd, unsigned int const Mode, CompressMode Compress, bool AutoClose=false);
    bool OpenDescriptor(int Fd, unsigned int const Mode, APT::Configuration::Compressor const &compressor, bool AutoClose=false);
    inline bool OpenDescriptor(int Fd, unsigned int const Mode, bool AutoClose=false) {
-      if (Mode == ReadOnlyGzip)
-         return OpenDescriptor(Fd, Mode, Gzip, AutoClose);
-      else
-         return OpenDescriptor(Fd, Mode, None, AutoClose);
+      return OpenDescriptor(Fd, Mode, None, AutoClose);
    };
    bool Close();
    bool Sync();
@@ -174,6 +171,7 @@ std::vector<std::string> GetListOfFilesInDir(std::string const &Dir, std::string
                                        bool const &SortList, bool const &AllowNoExt=false);
 std::vector<std::string> GetListOfFilesInDir(std::string const &Dir, std::vector<std::string> const &Ext,
                                        bool const &SortList);
+std::vector<std::string> GetListOfFilesInDir(std::string const &Dir, bool SortList);
 std::string SafeGetCWD();
 void SetCloseExec(int Fd,bool Close);
 void SetNonBlock(int Fd,bool Block);
index 861cdcbeb6fa8b555dd0a1193981e92e1b1a2336..99efa8d98053bb1f5f0b9d0206685ff809585e4d 100644 (file)
@@ -910,17 +910,17 @@ bool StrToTime(const string &Val,time_t &Result)
 
    // Handle RFC 1123 time
    Month[0] = 0;
-   if (sscanf(I," %d %3s %d %d:%d:%d GMT",&Tm.tm_mday,Month,&Tm.tm_year,
+   if (sscanf(I," %2d %3s %4d %2d:%2d:%2d GMT",&Tm.tm_mday,Month,&Tm.tm_year,
              &Tm.tm_hour,&Tm.tm_min,&Tm.tm_sec) != 6)
    {
       // Handle RFC 1036 time
-      if (sscanf(I," %d-%3s-%d %d:%d:%d GMT",&Tm.tm_mday,Month,
+      if (sscanf(I," %2d-%3s-%3d %2d:%2d:%2d GMT",&Tm.tm_mday,Month,
                 &Tm.tm_year,&Tm.tm_hour,&Tm.tm_min,&Tm.tm_sec) == 6)
         Tm.tm_year += 1900;
       else
       {
         // asctime format
-        if (sscanf(I," %3s %d %d:%d:%d %d",Month,&Tm.tm_mday,
+        if (sscanf(I," %3s %2d %2d:%2d:%2d %4d",Month,&Tm.tm_mday,
                    &Tm.tm_hour,&Tm.tm_min,&Tm.tm_sec,&Tm.tm_year) != 6)
         {
            // 'ftp' time
index bdb50f6bff809ba9b7ebf22e8660dc243b244ae0..84e6c38c5440c90db4375da3e67ea740a7feb987 100644 (file)
@@ -249,7 +249,7 @@ bool debListParser::UsePackage(pkgCache::PkgIterator &Pkg,
       return false;
 
    if (strcmp(Pkg.Name(),"apt") == 0)
-      Pkg->Flags |= pkgCache::Flag::Important;
+      Pkg->Flags |= pkgCache::Flag::Essential | pkgCache::Flag::Important;
    
    if (ParseStatus(Pkg,Ver) == false)
       return false;
index 5d3a80aa56cc114c82ef0717637965512de3c59c..bcc617da7053524ab19bd87de30b39d29b453498 100644 (file)
@@ -128,7 +128,7 @@ string debReleaseIndex::TranslationIndexURISuffix(const char *Type, const string
 {
    string Res ="";
    if (Dist[Dist.size() - 1] != '/')
-      Res += Section + "/i18n/";
+      Res += Section + "/i18n/Translation-";
    return Res + Type;
 }
 
@@ -210,31 +210,17 @@ vector <struct IndexTarget *>* debReleaseIndex::ComputeIndexTargets() const {
        if (lang.empty() == true)
                return IndexTargets;
 
-       // get the Translations:
-       // - if its a dists-style repository get the i18n/Index first
-       // - if its flat try to acquire files by guessing
-       if (Dist[Dist.size() - 1] == '/') {
-               for (std::set<std::string>::const_iterator s = sections.begin();
-                    s != sections.end(); ++s) {
-                       for (std::vector<std::string>::const_iterator l = lang.begin();
-                            l != lang.end(); ++l) {
-                               IndexTarget * Target = new OptionalIndexTarget();
-                               Target->ShortDesc = "Translation-" + *l;
-                               Target->MetaKey = TranslationIndexURISuffix(l->c_str(), *s);
-                               Target->URI = TranslationIndexURI(l->c_str(), *s);
-                               Target->Description = Info (Target->ShortDesc.c_str(), *s);
-                               IndexTargets->push_back(Target);
-                       }
-               }
-       } else {
-               for (std::set<std::string>::const_iterator s = sections.begin();
-                    s != sections.end(); ++s) {
-                       IndexTarget * Target = new OptionalSubIndexTarget();
-                       Target->ShortDesc = "TranslationIndex";
-                       Target->MetaKey = TranslationIndexURISuffix("Index", *s);
-                       Target->URI = TranslationIndexURI("Index", *s);
+       // get the Translation-* files, later we will skip download of non-existent if we have an index
+       for (std::set<std::string>::const_iterator s = sections.begin();
+            s != sections.end(); ++s) {
+               for (std::vector<std::string>::const_iterator l = lang.begin();
+                    l != lang.end(); ++l) {
+                       IndexTarget * Target = new OptionalIndexTarget();
+                       Target->ShortDesc = "Translation-" + *l;
+                       Target->MetaKey = TranslationIndexURISuffix(l->c_str(), *s);
+                       Target->URI = TranslationIndexURI(l->c_str(), *s);
                        Target->Description = Info (Target->ShortDesc.c_str(), *s);
-                       IndexTargets->push_back (Target);
+                       IndexTargets->push_back(Target);
                }
        }
 
index 8c63b0c9bd4154594c92aaf47b4886d2a6050783..c46a812095cd17e97ce3e24aa6f5cb6af4790d50 100644 (file)
@@ -51,8 +51,10 @@ using namespace std;
 class pkgDPkgPMPrivate 
 {
 public:
-   pkgDPkgPMPrivate() : dpkgbuf_pos(0), term_out(NULL), history_out(NULL)
+   pkgDPkgPMPrivate() : stdin_is_dev_null(false), dpkgbuf_pos(0),
+                       term_out(NULL), history_out(NULL)
    {
+      dpkgbuf[0] = '\0';
    }
    bool stdin_is_dev_null;
    // the buffer we use for the dpkg status-fd reading
@@ -860,6 +862,8 @@ static int racy_pselect(int nfds, fd_set *readfds, fd_set *writefds,
 */
 bool pkgDPkgPM::Go(int OutStatusFd)
 {
+   pkgPackageManager::SigINTStop = false;
+
    // Generate the base argument list for dpkg
    std::vector<const char *> Args;
    unsigned long StartSize = 0;
@@ -905,7 +909,7 @@ bool pkgDPkgPM::Go(int OutStatusFd)
       dup2(nullfd, STDIN_FILENO);
       dup2(nullfd, STDOUT_FILENO);
       dup2(nullfd, STDERR_FILENO);
-      execv(Args[0], (char**) &Args[0]);
+      execvp(Args[0], (char**) &Args[0]);
       _error->WarningE("dpkgGo", "Can't detect if dpkg supports multi-arch!");
       _exit(2);
    }
@@ -1429,9 +1433,8 @@ bool pkgDPkgPM::Go(int OutStatusFd)
 }
 
 void SigINT(int sig) {
-   if (_config->FindB("APT::Immediate-Configure-All",false)) 
-      pkgPackageManager::SigINTStop = true;
-} 
+   pkgPackageManager::SigINTStop = true;
+}
                                                                        /*}}}*/
 // pkgDpkgPM::Reset - Dump the contents of the command list            /*{{{*/
 // ---------------------------------------------------------------------
@@ -1446,6 +1449,12 @@ void pkgDPkgPM::Reset()
 /* */
 void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg) 
 {
+   // If apport doesn't exist or isn't installed do nothing
+   // This e.g. prevents messages in 'universes' without apport
+   pkgCache::PkgIterator apportPkg = Cache.FindPkg("apport");
+   if (apportPkg.end() == true || apportPkg->CurrentVer == 0)
+      return;
+
    string pkgname, reportfile, srcpkgname, pkgver, arch;
    string::size_type pos;
    FILE *report;
@@ -1533,7 +1542,7 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg)
         if(strstr(strbuf,"Package:") == strbuf)
         {
            char pkgname[255], version[255];
-           if(sscanf(strbuf, "Package: %s %s", pkgname, version) == 2)
+           if(sscanf(strbuf, "Package: %254s %254s", pkgname, version) == 2)
               if(strcmp(pkgver.c_str(), version) == 0)
               {
                  fclose(report);
index 9449c73066e4f61996163f67ef94b1fa802c91ca..1eea5556026d02d90a667d77ede3d8dbffd423eb 100644 (file)
@@ -963,6 +963,13 @@ struct CompareProviders {
         else if ((B->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
            return true;
       }
+      if ((A->Flags & pkgCache::Flag::Important) != (B->Flags & pkgCache::Flag::Important))
+      {
+        if ((A->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important)
+           return false;
+        else if ((B->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important)
+           return true;
+      }
       // higher priority seems like a good idea
       if (AV->Priority != BV->Priority)
         return AV->Priority < BV->Priority;
@@ -1641,6 +1648,7 @@ bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc)
    {
       if(!(PkgState[p->ID].Flags & Flag::Auto) ||
          (p->Flags & Flag::Essential) ||
+         (p->Flags & Flag::Important) ||
          userFunc.InRootSet(p) ||
          // be nice even then a required package violates the policy (#583517)
          // and do the full mark process also for required packages
index 3747e357003a1cd0e8ae05f468a833bf745bd241..e29e2819cb5eb5a806da8a757624999cc2534a06 100644 (file)
@@ -85,7 +85,7 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List,
       string OrigPath = string(*I,CDROM.length());
       
       // Open the package file
-      FileFd Pkg(*I + GetFileName(), FileFd::ReadOnly, FileFd::Extension);
+      FileFd Pkg(*I + GetFileName(), FileFd::ReadOnly, FileFd::Auto);
       off_t const FileSize = Pkg.Size();
 
       pkgTagFile Parser(&Pkg);
@@ -797,7 +797,7 @@ bool TranslationsCopy::CopyTranslations(string CDROM,string Name,   /*{{{*/
       string OrigPath = string(*I,CDROM.length());
 
       // Open the package file
-      FileFd Pkg(*I, FileFd::ReadOnly, FileFd::Extension);
+      FileFd Pkg(*I, FileFd::ReadOnly, FileFd::Auto);
       off_t const FileSize = Pkg.Size();
 
       pkgTagFile Parser(&Pkg);
index cdb9250e821f9567d88bc3e5476f40629c06f072..af2639beb851cfb125bf84b072c9aab2109e4daf 100644 (file)
@@ -44,7 +44,10 @@ time_t indexRecords::GetValidUntil() const
 
 const indexRecords::checkSum *indexRecords::Lookup(const string MetaKey)
 {
-   return Entries[MetaKey];
+   std::map<std::string, indexRecords::checkSum* >::const_iterator sum = Entries.find(MetaKey);
+   if (sum == Entries.end())
+      return NULL;
+   return sum->second;
 }
 
 bool indexRecords::Exists(string const &MetaKey) const
index 0ac9a83e3b14c1971e7dc863022d00279ad2d042..3a179b2a282f347f2594291148576dd5246f4381 100644 (file)
@@ -82,16 +82,14 @@ pkgOrderList *pkgOrderList::Me = 0;
 // OrderList::pkgOrderList - Constructor                               /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-pkgOrderList::pkgOrderList(pkgDepCache *pCache) : Cache(*pCache)
+pkgOrderList::pkgOrderList(pkgDepCache *pCache) : Cache(*pCache),
+                                                 Primary(NULL), Secondary(NULL),
+                                                 RevDepends(NULL), Remove(NULL),
+                                                 AfterEnd(NULL), FileList(NULL),
+                                                 LoopCount(-1), Depth(0)
 {
-   FileList = 0;
-   Primary = 0;
-   Secondary = 0;
-   RevDepends = 0;
-   Remove = 0;
-   LoopCount = -1;
    Debug = _config->FindB("Debug::pkgOrderList",false);
-   
+
    /* Construct the arrays, egcs 1.0.1 bug requires the package count
       hack */
    unsigned long Size = Cache.Head().PackageCount;
index 701b64af1d9395ec278e17c6625f01f34fc96137..698c8606f21c5b67f9015bfa33c413fbd374dce7 100644 (file)
@@ -36,11 +36,13 @@ bool pkgPackageManager::SigINTStop = false;
 // PM::PackageManager - Constructor                                    /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-pkgPackageManager::pkgPackageManager(pkgDepCache *pCache) : Cache(*pCache)
+pkgPackageManager::pkgPackageManager(pkgDepCache *pCache) : Cache(*pCache),
+                                                           List(NULL), Res(Incomplete)
 {
    FileNames = new string[Cache.Head().PackageCount];
-   List = 0;
    Debug = _config->FindB("Debug::pkgPackageManager",false);
+   NoImmConfigure = !_config->FindB("APT::Immediate-Configure",true);
+   ImmConfigureAll = _config->FindB("APT::Immediate-Configure-All",false);
 }
                                                                        /*}}}*/
 // PM::PackageManager - Destructor                                     /*{{{*/
@@ -150,7 +152,7 @@ void pkgPackageManager::ImmediateAdd(PkgIterator I, bool UseInstallVer, unsigned
         if(!List->IsFlag(D.TargetPkg(), pkgOrderList::Immediate))
         {
            if(Debug)
-              clog << OutputInDepth(Depth) << "ImmediateAdd(): Adding Immediate flag to " << D.TargetPkg() << " cause of " << D.DepType() << " " << I.Name() << endl;
+              clog << OutputInDepth(Depth) << "ImmediateAdd(): Adding Immediate flag to " << D.TargetPkg() << " cause of " << D.DepType() << " " << I.FullName() << endl;
            List->Flag(D.TargetPkg(),pkgOrderList::Immediate);
            ImmediateAdd(D.TargetPkg(), UseInstallVer, Depth + 1);
         }
@@ -169,10 +171,7 @@ bool pkgPackageManager::CreateOrderList()
    
    delete List;
    List = new pkgOrderList(&Cache);
-   
-   NoImmConfigure = !_config->FindB("APT::Immediate-Configure",true);
-   ImmConfigureAll = _config->FindB("APT::Immediate-Configure-All",false);
-   
+
    if (Debug && ImmConfigureAll) 
       clog << "CreateOrderList(): Adding Immediate flag for all packages because of APT::Immediate-Configure-All" << endl;
    
@@ -184,12 +183,11 @@ bool pkgPackageManager::CreateOrderList()
         continue;
       
       // Mark the package and its dependends for immediate configuration
-      if ((((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential ||
-          (I->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important) &&
+      if ((((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) &&
          NoImmConfigure == false) || ImmConfigureAll)
       {
         if(Debug && !ImmConfigureAll)
-           clog << "CreateOrderList(): Adding Immediate flag for " << I.Name() << endl;
+           clog << "CreateOrderList(): Adding Immediate flag for " << I.FullName() << endl;
         List->Flag(I,pkgOrderList::Immediate);
         
         if (!ImmConfigureAll) {
@@ -258,7 +256,7 @@ bool pkgPackageManager::CheckRConflicts(PkgIterator Pkg,DepIterator D,
 
       if (EarlyRemove(D.ParentPkg()) == false)
         return _error->Error("Reverse conflicts early remove for package '%s' failed",
-                             Pkg.Name());
+                             Pkg.FullName().c_str());
    }
    return true;
 }
@@ -296,9 +294,9 @@ bool pkgPackageManager::ConfigureAll()
       if (ConfigurePkgs == true && SmartConfigure(Pkg, 0) == false) {
          if (ImmConfigureAll)
             _error->Error(_("Could not perform immediate configuration on '%s'. "
-                       "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.Name(),1);
+                       "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.FullName().c_str(),1);
          else
-            _error->Error("Internal error, packages left unconfigured. %s",Pkg.Name());
+            _error->Error("Internal error, packages left unconfigured. %s",Pkg.FullName().c_str());
         return false;
       }
       
@@ -323,11 +321,11 @@ bool pkgPackageManager::ConfigureAll()
 bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth)
 {
    // If this is true, only check and correct and dependencies without the Loop flag
-   bool PkgLoop = List->IsFlag(Pkg,pkgOrderList::Loop);
+   bool const PkgLoop = List->IsFlag(Pkg,pkgOrderList::Loop);
 
    if (Debug) {
       VerIterator InstallVer = VerIterator(Cache,Cache[Pkg].InstallVer);
-      clog << OutputInDepth(Depth) << "SmartConfigure " << Pkg.Name() << " (" << InstallVer.VerStr() << ")";
+      clog << OutputInDepth(Depth) << "SmartConfigure " << Pkg.FullName() << " (" << InstallVer.VerStr() << ")";
       if (PkgLoop)
         clog << " (Only Correct Dependencies)";
       clog << endl;
@@ -338,103 +336,135 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth)
    /* Because of the ordered list, most dependencies should be unpacked, 
       however if there is a loop (A depends on B, B depends on A) this will not 
       be the case, so check for dependencies before configuring. */
-   bool Bad = false;
-   for (DepIterator D = instVer.DependsList();
-       D.end() == false; )
-   {
-      // Compute a single dependency element (glob or)
-      pkgCache::DepIterator Start;
-      pkgCache::DepIterator End;
-      D.GlobOr(Start,End);
-      
-      if (End->Type == pkgCache::Dep::Depends) 
-          Bad = true;
-
-      // Check for dependanices that have not been unpacked, probably due to loops.
-      while (End->Type == pkgCache::Dep::Depends) {
-         PkgIterator DepPkg;
-         VerIterator InstallVer;
-         SPtrArray<Version *> VList = Start.AllTargets();
-         
-         // Check through each version of each package that could satisfy this dependancy
-        for (Version **I = VList; *I != 0; I++) {
-           VerIterator Ver(Cache,*I);
-           DepPkg = Ver.ParentPkg();
-           InstallVer = VerIterator(Cache,Cache[DepPkg].InstallVer);
-
-           // Check if the current version of the package is avalible and will satisfy this dependancy
-           if (DepPkg.CurrentVer() == Ver && List->IsNow(DepPkg) == true && 
-               !List->IsFlag(DepPkg,pkgOrderList::Removed) && DepPkg.State() == PkgIterator::NeedsNothing)
+   bool Bad = false, Changed = false;
+   do {
+      Changed = false;
+      for (DepIterator D = instVer.DependsList(); D.end() == false; )
+      {
+        // Compute a single dependency element (glob or)
+        pkgCache::DepIterator Start, End;
+        D.GlobOr(Start,End);
+
+        if (End->Type != pkgCache::Dep::Depends)
+           continue;
+        Bad = true;
+
+        // Search for dependencies which are unpacked but aren't configured yet (maybe loops)
+        for (DepIterator Cur = Start; true; ++Cur)
+        {
+           SPtrArray<Version *> VList = Cur.AllTargets();
+
+           for (Version **I = VList; *I != 0; ++I)
            {
-              Bad = false;
-              break;
-           }
-           
-           // Check if the version that is going to be installed will satisfy the dependancy
-           if (Cache[DepPkg].InstallVer == *I) {
-              if (List->IsFlag(DepPkg,pkgOrderList::UnPacked)) {
-                 if (List->IsFlag(DepPkg,pkgOrderList::Loop) && PkgLoop) {
-                   // This dependancy has already been dealt with by another SmartConfigure on Pkg
-                   Bad = false;
-                   break;
-                  } else if (List->IsFlag(Pkg,pkgOrderList::Loop)) {
-                   /* Check for a loop to prevent one forming
-                      If A depends on B and B depends on A, SmartConfigure will
-                      just hop between them if this is not checked. Dont remove the 
-                      loop flag after finishing however as loop is already set.
-                      This means that there is another SmartConfigure call for this 
-                      package and it will remove the loop flag */
-                    Bad = !SmartConfigure(DepPkg, Depth + 1);
-                 } else {
-                   /* Check for a loop to prevent one forming
-                      If A depends on B and B depends on A, SmartConfigure will
-                      just hop between them if this is not checked */
-                   List->Flag(Pkg,pkgOrderList::Loop);
-                   Bad = !SmartConfigure(DepPkg, Depth + 1);
-                   List->RmFlag(Pkg,pkgOrderList::Loop);
-                 }
-                 // If SmartConfigure was succesfull, Bad is false, so break
-                 if (!Bad) break;
-              } else if (List->IsFlag(DepPkg,pkgOrderList::Configured)) {
-                 Bad = false;
-                 break;
+              VerIterator Ver(Cache,*I);
+              PkgIterator DepPkg = Ver.ParentPkg();
+
+              // Check if the current version of the package is available and will satisfy this dependency
+              if (DepPkg.CurrentVer() == Ver && List->IsNow(DepPkg) == true &&
+                  List->IsFlag(DepPkg,pkgOrderList::Removed) == false &&
+                  DepPkg.State() == PkgIterator::NeedsNothing)
+              {
+                 Bad = false;
+                 break;
+              }
+
+              // Check if the version that is going to be installed will satisfy the dependency
+              if (Cache[DepPkg].InstallVer != *I)
+                 continue;
+
+              if (List->IsFlag(DepPkg,pkgOrderList::UnPacked))
+              {
+                 if (List->IsFlag(DepPkg,pkgOrderList::Loop) && PkgLoop)
+                 {
+                   // This dependency has already been dealt with by another SmartConfigure on Pkg
+                   Bad = false;
+                   break;
+                 }
+                 /* Check for a loop to prevent one forming
+                      If A depends on B and B depends on A, SmartConfigure will
+                      just hop between them if this is not checked. Dont remove the
+                      loop flag after finishing however as loop is already set.
+                      This means that there is another SmartConfigure call for this
+                      package and it will remove the loop flag */
+                 if (PkgLoop == false)
+                    List->Flag(Pkg,pkgOrderList::Loop);
+                 if (SmartConfigure(DepPkg, Depth + 1) == true)
+                 {
+                    Bad = false;
+                    if (List->IsFlag(DepPkg,pkgOrderList::Loop) == false)
+                       Changed = true;
+                 }
+                 if (PkgLoop == false)
+                   List->RmFlag(Pkg,pkgOrderList::Loop);
+                 // If SmartConfigure was succesfull, Bad is false, so break
+                 if (Bad == false)
+                    break;
+              }
+              else if (List->IsFlag(DepPkg,pkgOrderList::Configured))
+              {
+                 Bad = false;
+                 break;
               }
            }
-        }
-        
-        /* If the dependany is still not satisfied, try, if possible, unpacking a package to satisfy it */
-        if (InstallVer != 0 && Bad) {
-           if (List->IsNow(DepPkg)) {
-              Bad = false;
-              if (List->IsFlag(Pkg,pkgOrderList::Loop))
+           if (Cur == End)
+              break;
+         }
+
+        if (Bad == false)
+           continue;
+
+        // Check for dependencies that have not been unpacked, probably due to loops.
+        for (DepIterator Cur = Start; true; ++Cur)
+        {
+           SPtrArray<Version *> VList = Cur.AllTargets();
+
+           for (Version **I = VList; *I != 0; ++I)
+           {
+              VerIterator Ver(Cache,*I);
+              PkgIterator DepPkg = Ver.ParentPkg();
+
+              // Check if the version that is going to be installed will satisfy the dependency
+              if (Cache[DepPkg].InstallVer != *I || List->IsNow(DepPkg) == false)
+                 continue;
+
+              if (PkgLoop == true)
               {
                  if (Debug)
                     std::clog << OutputInDepth(Depth) << "Package " << Pkg << " loops in SmartConfigure" << std::endl;
+                 Bad = false;
+                 break;
               }
               else
               {
-                 List->Flag(Pkg,pkgOrderList::Loop);
                  if (Debug)
-                    cout << OutputInDepth(Depth) << "Unpacking " << DepPkg.Name() << " to avoid loop" << endl;
-                 SmartUnPack(DepPkg, true, Depth + 1);
-                 List->RmFlag(Pkg,pkgOrderList::Loop);
+                    clog << OutputInDepth(Depth) << "Unpacking " << DepPkg.FullName() << " to avoid loop " << Cur << endl;
+                 if (PkgLoop == false)
+                    List->Flag(Pkg,pkgOrderList::Loop);
+                 if (SmartUnPack(DepPkg, true, Depth + 1) == true)
+                 {
+                    Bad = false;
+                    if (List->IsFlag(DepPkg,pkgOrderList::Loop) == false)
+                       Changed = true;
+                 }
+                 if (PkgLoop == false)
+                    List->RmFlag(Pkg,pkgOrderList::Loop);
+                 if (Bad == false)
+                    break;
               }
            }
+
+           if (Cur == End)
+              break;
         }
-        
-        if (Start==End) {
-           if (Bad && Debug && List->IsFlag(DepPkg,pkgOrderList::Loop) == false)
-                 std::clog << OutputInDepth(Depth) << "Could not satisfy dependencies for " << Pkg.Name() << std::endl;
-           break;
-        } else {
-            Start++;
-         }
+
+        if (Bad == true && Changed == false && Debug == true)
+           std::clog << OutputInDepth(Depth) << "Could not satisfy " << Start << std::endl;
       }
-   }
+   } while (Changed == true);
    
    if (Bad) {
       if (Debug)
-         _error->Warning(_("Could not configure '%s'. "),Pkg.Name());
+         _error->Warning(_("Could not configure '%s'. "),Pkg.FullName().c_str());
       return false;
    }
    
@@ -444,7 +474,7 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth)
    static bool const ConfigurePkgs = (conf == "all" || conf == "smart");
 
    if (List->IsFlag(Pkg,pkgOrderList::Configured)) 
-      return _error->Error("Internal configure error on '%s'.", Pkg.Name());
+      return _error->Error("Internal configure error on '%s'.", Pkg.FullName().c_str());
 
    if (ConfigurePkgs == true && Configure(Pkg) == false)
       return false;
@@ -464,7 +494,7 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth)
 
    // Sanity Check
    if (List->IsFlag(Pkg,pkgOrderList::Configured) == false)
-      return _error->Error(_("Could not configure '%s'. "),Pkg.Name());
+      return _error->Error(_("Could not configure '%s'. "),Pkg.FullName().c_str());
 
    return true;
 }
@@ -487,7 +517,8 @@ bool pkgPackageManager::EarlyRemove(PkgIterator Pkg)
 
    // Essential packages get special treatment
    bool IsEssential = false;
-   if ((Pkg->Flags & pkgCache::Flag::Essential) != 0)
+   if ((Pkg->Flags & pkgCache::Flag::Essential) != 0 ||
+       (Pkg->Flags & pkgCache::Flag::Important) != 0)
       IsEssential = true;
 
    /* Check for packages that are the dependents of essential packages and 
@@ -497,7 +528,8 @@ bool pkgPackageManager::EarlyRemove(PkgIterator Pkg)
       for (DepIterator D = Pkg.RevDependsList(); D.end() == false &&
           IsEssential == false; ++D)
         if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends)
-           if ((D.ParentPkg()->Flags & pkgCache::Flag::Essential) != 0)
+           if ((D.ParentPkg()->Flags & pkgCache::Flag::Essential) != 0 ||
+               (D.ParentPkg()->Flags & pkgCache::Flag::Important) != 0)
               IsEssential = true;
    }
 
@@ -508,7 +540,7 @@ bool pkgPackageManager::EarlyRemove(PkgIterator Pkg)
                                "removing the essential package %s due to a "
                                "Conflicts/Pre-Depends loop. This is often bad, "
                                "but if you really want to do it, activate the "
-                               "APT::Force-LoopBreak option."),Pkg.Name());
+                               "APT::Force-LoopBreak option."),Pkg.FullName().c_str());
    }
    
    bool Res = SmartRemove(Pkg);
@@ -544,193 +576,252 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate, int c
    bool PkgLoop = List->IsFlag(Pkg,pkgOrderList::Loop);
 
    if (Debug) {
-      clog << OutputInDepth(Depth) << "SmartUnPack " << Pkg.Name();
+      clog << OutputInDepth(Depth) << "SmartUnPack " << Pkg.FullName();
       VerIterator InstallVer = VerIterator(Cache,Cache[Pkg].InstallVer);
       if (Pkg.CurrentVer() == 0)
-        cout << " (install version " << InstallVer.VerStr() << ")";
+        clog << " (install version " << InstallVer.VerStr() << ")";
       else
-        cout << " (replace version " << Pkg.CurrentVer().VerStr() << " with " << InstallVer.VerStr() << ")";
+        clog << " (replace version " << Pkg.CurrentVer().VerStr() << " with " << InstallVer.VerStr() << ")";
       if (PkgLoop)
-        cout << " (Only Perform PreUnpack Checks)";
-      cout << endl;
+        clog << " (Only Perform PreUnpack Checks)";
+      clog << endl;
    }
 
    VerIterator const instVer = Cache[Pkg].InstVerIter(Cache);
 
    /* PreUnpack Checks: This loop checks and attempts to rectify and problems that would prevent the package being unpacked.
-      It addresses: PreDepends, Conflicts, Obsoletes and Breaks (DpkgBreaks). Any resolutions that do not require it should 
+      It addresses: PreDepends, Conflicts, Obsoletes and Breaks (DpkgBreaks). Any resolutions that do not require it should
       avoid configuration (calling SmartUnpack with Immediate=true), this is because when unpacking some packages with
-      complex dependancy structures, trying to configure some packages while breaking the loops can complicate things . 
-      This will be either dealt with if the package is configured as a dependency of Pkg (if and when Pkg is configured), 
+      complex dependancy structures, trying to configure some packages while breaking the loops can complicate things .
+      This will be either dealt with if the package is configured as a dependency of Pkg (if and when Pkg is configured),
       or by the ConfigureAll call at the end of the for loop in OrderInstall. */
-   for (DepIterator D = instVer.DependsList();
-       D.end() == false; )
-   {
-      // Compute a single dependency element (glob or)
-      pkgCache::DepIterator Start;
-      pkgCache::DepIterator End;
-      D.GlobOr(Start,End);
-      
-      while (End->Type == pkgCache::Dep::PreDepends)
+   bool Changed = false;
+   do {
+      Changed = false;
+      for (DepIterator D = instVer.DependsList(); D.end() == false; )
       {
-        if (Debug)
-           clog << OutputInDepth(Depth) << "PreDepends order for " << Pkg.Name() << std::endl;
-
-        // Look for possible ok targets.
-        SPtrArray<Version *> VList = Start.AllTargets();
-        bool Bad = true;
-        for (Version **I = VList; *I != 0 && Bad == true; I++)
-        {
-           VerIterator Ver(Cache,*I);
-           PkgIterator Pkg = Ver.ParentPkg();
-           
-           // See if the current version is ok
-           if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true && 
-               Pkg.State() == PkgIterator::NeedsNothing)
+        // Compute a single dependency element (glob or)
+        pkgCache::DepIterator Start, End;
+        D.GlobOr(Start,End);
+
+        if (End->Type == pkgCache::Dep::PreDepends)
+         {
+           bool Bad = true;
+           if (Debug)
+              clog << OutputInDepth(Depth) << "PreDepends order for " << Pkg.FullName() << std::endl;
+
+           // Look for easy targets: packages that are already okay
+           for (DepIterator Cur = Start; Bad == true; ++Cur)
            {
-              Bad = false;
-              if (Debug)
-                 clog << OutputInDepth(Depth) << "Found ok package " << Pkg.Name() << endl;
-              continue;
-           }
-        }
-        
-        // Look for something that could be configured.
-        for (Version **I = VList; *I != 0 && Bad == true; I++)
-        {
-           VerIterator Ver(Cache,*I);
-           PkgIterator Pkg = Ver.ParentPkg();
-           
-           // Not the install version 
-           if (Cache[Pkg].InstallVer != *I || 
-               (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing))
-              continue;
-              
-           if (List->IsFlag(Pkg,pkgOrderList::Configured)) {
-              Bad = false;
-              continue;
+              SPtrArray<Version *> VList = Start.AllTargets();
+              for (Version **I = VList; *I != 0; ++I)
+              {
+                 VerIterator Ver(Cache,*I);
+                 PkgIterator Pkg = Ver.ParentPkg();
+
+                 // See if the current version is ok
+                 if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true &&
+                     Pkg.State() == PkgIterator::NeedsNothing)
+                 {
+                    Bad = false;
+                    if (Debug)
+                       clog << OutputInDepth(Depth) << "Found ok package " << Pkg.FullName() << endl;
+                    break;
+                 }
+              }
+              if (Cur == End)
+                 break;
            }
 
-            // check if it needs unpack or if if configure is enough
-            if (!List->IsFlag(Pkg,pkgOrderList::UnPacked))
-            {
-               if (Debug)
-                  clog << OutputInDepth(Depth) << "Trying to SmartUnpack " << Pkg.Name() << endl;
-               // SmartUnpack with the ImmediateFlag to ensure its really ready
-               Bad = !SmartUnPack(Pkg, true, Depth + 1);
-            } else {
-               if (Debug)
-                  clog << OutputInDepth(Depth) << "Trying to SmartConfigure " << Pkg.Name() << endl;
-               Bad = !SmartConfigure(Pkg, Depth + 1);
-            }
-         }
+           // Look for something that could be configured.
+           for (DepIterator Cur = Start; Bad == true; ++Cur)
+           {
+              SPtrArray<Version *> VList = Start.AllTargets();
+              for (Version **I = VList; *I != 0; ++I)
+              {
+                 VerIterator Ver(Cache,*I);
+                 PkgIterator Pkg = Ver.ParentPkg();
+
+                 // Not the install version
+                 if (Cache[Pkg].InstallVer != *I ||
+                     (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing))
+                    continue;
+
+                 if (List->IsFlag(Pkg,pkgOrderList::Configured))
+                 {
+                    Bad = false;
+                    break;
+                 }
+
+                 // check if it needs unpack or if if configure is enough
+                 if (List->IsFlag(Pkg,pkgOrderList::UnPacked) == false)
+                 {
+                    if (Debug)
+                       clog << OutputInDepth(Depth) << "Trying to SmartUnpack " << Pkg.FullName() << endl;
+                    // SmartUnpack with the ImmediateFlag to ensure its really ready
+                    if (SmartUnPack(Pkg, true, Depth + 1) == true)
+                    {
+                       Bad = false;
+                       if (List->IsFlag(Pkg,pkgOrderList::Loop) == false)
+                          Changed = true;
+                       break;
+                    }
+                 }
+                 else
+                 {
+                    if (Debug)
+                       clog << OutputInDepth(Depth) << "Trying to SmartConfigure " << Pkg.FullName() << endl;
+                    if (SmartConfigure(Pkg, Depth + 1) == true)
+                    {
+                       Bad = false;
+                       if (List->IsFlag(Pkg,pkgOrderList::Loop) == false)
+                          Changed = true;
+                       break;
+                    }
+                 }
+              }
+           }
 
-        /* If this or element did not match then continue on to the
-           next or element until a matching element is found */
-        if (Bad == true)
-        {
-           // This triggers if someone make a pre-depends/depend loop.
-           if (Start == End)
-              return _error->Error("Couldn't configure pre-depend %s for %s, "
-                                   "probably a dependency cycle.",
-                                   End.TargetPkg().Name(),Pkg.Name());
-           ++Start;
+           if (Bad == true)
+           {
+              if (Start == End)
+                 return _error->Error("Couldn't configure pre-depend %s for %s, "
+                                       "probably a dependency cycle.",
+                                       End.TargetPkg().FullName().c_str(),Pkg.FullName().c_str());
+           }
+           else
+              continue;
         }
-        else 
-           break;
-      }
-      
-      if (End->Type == pkgCache::Dep::Conflicts || 
-         End->Type == pkgCache::Dep::Obsoletes)
-      {
-        /* Look for conflicts. Two packages that are both in the install
-           state cannot conflict so we don't check.. */
-        SPtrArray<Version *> VList = End.AllTargets();
-        for (Version **I = VList; *I != 0; I++)
+        else if (End->Type == pkgCache::Dep::Conflicts ||
+                 End->Type == pkgCache::Dep::Obsoletes)
         {
-           VerIterator Ver(Cache,*I);
-           PkgIterator ConflictPkg = Ver.ParentPkg();
-           VerIterator InstallVer(Cache,Cache[ConflictPkg].InstallVer);
-           
-           // See if the current version is conflicting
-           if (ConflictPkg.CurrentVer() == Ver && List->IsNow(ConflictPkg))
-           { 
-              cout << OutputInDepth(Depth) << Pkg.Name() << " conflicts with " << ConflictPkg.Name() << endl;
-              /* If a loop is not present or has not yet been detected, attempt to unpack packages 
-                 to resolve this conflict. If there is a loop present, remove packages to resolve this conflict */
-              if (!List->IsFlag(ConflictPkg,pkgOrderList::Loop)) {
-                 if (Cache[ConflictPkg].Keep() == 0 && Cache[ConflictPkg].InstallVer != 0) {
-                     if (Debug)
-                        cout << OutputInDepth(Depth) << OutputInDepth(Depth) << "Unpacking " << ConflictPkg.Name() << " to prevent conflict" << endl;
-                      List->Flag(Pkg,pkgOrderList::Loop);
-                     SmartUnPack(ConflictPkg,false, Depth + 1);
-                     // Remove loop to allow it to be used later if needed
-                     List->RmFlag(Pkg,pkgOrderList::Loop);
-                  } else {
-                      if (EarlyRemove(ConflictPkg) == false)
-                         return _error->Error("Internal Error, Could not early remove %s",ConflictPkg.Name());
-                  }
-              } else {
-                 if (!List->IsFlag(ConflictPkg,pkgOrderList::Removed)) {
-                     if (Debug)
-                         cout << OutputInDepth(Depth) << "Because of conficts knot, removing " << ConflictPkg.Name() << " to conflict violation" << endl;
-                     if (EarlyRemove(ConflictPkg) == false)
-                          return _error->Error("Internal Error, Could not early remove %s",ConflictPkg.Name());
-                 }
+           /* Look for conflicts. Two packages that are both in the install
+              state cannot conflict so we don't check.. */
+           SPtrArray<Version *> VList = End.AllTargets();
+           for (Version **I = VList; *I != 0; I++)
+           {
+              VerIterator Ver(Cache,*I);
+              PkgIterator ConflictPkg = Ver.ParentPkg();
+              VerIterator InstallVer(Cache,Cache[ConflictPkg].InstallVer);
+
+              // See if the current version is conflicting
+              if (ConflictPkg.CurrentVer() == Ver && List->IsNow(ConflictPkg))
+              {
+                 clog << OutputInDepth(Depth) << Pkg.FullName() << " conflicts with " << ConflictPkg.FullName() << endl;
+                 /* If a loop is not present or has not yet been detected, attempt to unpack packages
+                    to resolve this conflict. If there is a loop present, remove packages to resolve this conflict */
+                 if (List->IsFlag(ConflictPkg,pkgOrderList::Loop) == false)
+                 {
+                    if (Cache[ConflictPkg].Keep() == 0 && Cache[ConflictPkg].InstallVer != 0)
+                    {
+                       if (Debug)
+                          clog << OutputInDepth(Depth) << OutputInDepth(Depth) << "Unpacking " << ConflictPkg.FullName() << " to prevent conflict" << endl;
+                       List->Flag(Pkg,pkgOrderList::Loop);
+                       if (SmartUnPack(ConflictPkg,false, Depth + 1) == true)
+                          if (List->IsFlag(ConflictPkg,pkgOrderList::Loop) == false)
+                             Changed = true;
+                       // Remove loop to allow it to be used later if needed
+                       List->RmFlag(Pkg,pkgOrderList::Loop);
+                    }
+                    else if (EarlyRemove(ConflictPkg) == false)
+                       return _error->Error("Internal Error, Could not early remove %s (1)",ConflictPkg.FullName().c_str());
+                 }
+                 else if (List->IsFlag(ConflictPkg,pkgOrderList::Removed) == false)
+                 {
+                    if (Debug)
+                       clog << OutputInDepth(Depth) << "Because of conficts knot, removing " << ConflictPkg.FullName() << " to conflict violation" << endl;
+                    if (EarlyRemove(ConflictPkg) == false)
+                       return _error->Error("Internal Error, Could not early remove %s (2)",ConflictPkg.FullName().c_str());
+                 }
               }
            }
         }
-      }
-      
-      // Check for breaks
-      if (End->Type == pkgCache::Dep::DpkgBreaks) {
-         SPtrArray<Version *> VList = End.AllTargets();
-        for (Version **I = VList; *I != 0; I++)
+        else if (End->Type == pkgCache::Dep::DpkgBreaks)
         {
-           VerIterator Ver(Cache,*I);
-           PkgIterator BrokenPkg = Ver.ParentPkg();
-           VerIterator InstallVer(Cache,Cache[BrokenPkg].InstallVer);
-           if (BrokenPkg.CurrentVer() != Ver)
+           SPtrArray<Version *> VList = End.AllTargets();
+           for (Version **I = VList; *I != 0; ++I)
            {
-              if (Debug)
-                 std::clog << OutputInDepth(Depth) << "  Ignore not-installed version " << Ver.VerStr() << " of " << Pkg.FullName() << " for " << End << std::endl;
-              continue;
-           }
+              VerIterator Ver(Cache,*I);
+              PkgIterator BrokenPkg = Ver.ParentPkg();
+              if (BrokenPkg.CurrentVer() != Ver)
+              {
+                 if (Debug)
+                    std::clog << OutputInDepth(Depth) << "  Ignore not-installed version " << Ver.VerStr() << " of " << Pkg.FullName() << " for " << End << std::endl;
+                 continue;
+              }
 
-           // Check if it needs to be unpacked
-           if (List->IsFlag(BrokenPkg,pkgOrderList::InList) && Cache[BrokenPkg].Delete() == false && 
-               List->IsNow(BrokenPkg)) {
-             if (List->IsFlag(BrokenPkg,pkgOrderList::Loop) && PkgLoop) {
-               // This dependancy has already been dealt with by another SmartUnPack on Pkg
-               break;
-             } else if (List->IsFlag(Pkg,pkgOrderList::Loop)) {
-               /* Found a break, so unpack the package, but dont remove loop as already set.
-                  This means that there is another SmartUnPack call for this 
-                  package and it will remove the loop flag. */
-               if (Debug) 
-                 cout << OutputInDepth(Depth) << "  Unpacking " << BrokenPkg.Name() << " to avoid break" << endl;
-                   
-               SmartUnPack(BrokenPkg, false, Depth + 1);
-             } else {
-                List->Flag(Pkg,pkgOrderList::Loop);
-               // Found a break, so unpack the package
-               if (Debug) 
-                 cout << OutputInDepth(Depth) << "  Unpacking " << BrokenPkg.Name() << " to avoid break" << endl;
-                
-               SmartUnPack(BrokenPkg, false, Depth + 1);
-               List->RmFlag(Pkg,pkgOrderList::Loop);
-             }
-           }
-           
-           // Check if a package needs to be removed
-           if (Cache[BrokenPkg].Delete() == true && !List->IsFlag(BrokenPkg,pkgOrderList::Configured)) {
-             if (Debug) 
-                cout << OutputInDepth(Depth) << "  Removing " << BrokenPkg.Name() << " to avoid break" << endl;
-             SmartRemove(BrokenPkg);
+              // Check if it needs to be unpacked
+              if (List->IsFlag(BrokenPkg,pkgOrderList::InList) && Cache[BrokenPkg].Delete() == false &&
+                  List->IsNow(BrokenPkg))
+              {
+                 if (List->IsFlag(BrokenPkg,pkgOrderList::Loop) && PkgLoop)
+                 {
+                    // This dependancy has already been dealt with by another SmartUnPack on Pkg
+                    break;
+                 }
+                 else
+                 {
+                    // Found a break, so see if we can unpack the package to avoid it
+                    // but do not set loop if another SmartUnPack already deals with it
+                    // Also, avoid it if the package we would unpack pre-depends on this one
+                    VerIterator InstallVer(Cache,Cache[BrokenPkg].InstallVer);
+                    bool circle = false;
+                    for (pkgCache::DepIterator D = InstallVer.DependsList(); D.end() == false; ++D)
+                    {
+                       if (D->Type != pkgCache::Dep::PreDepends)
+                          continue;
+                       SPtrArray<Version *> VL = D.AllTargets();
+                       for (Version **I = VL; *I != 0; ++I)
+                       {
+                          VerIterator V(Cache,*I);
+                          PkgIterator P = V.ParentPkg();
+                          // we are checking for installation as an easy 'protection' against or-groups and (unchosen) providers
+                          if (P->CurrentVer == 0 || P != Pkg || (P.CurrentVer() != V && Cache[P].InstallVer != V))
+                             continue;
+                          circle = true;
+                          break;
+                       }
+                       if (circle == true)
+                          break;
+                    }
+                    if (circle == true)
+                    {
+                       if (Debug)
+                          clog << OutputInDepth(Depth) << "  Avoiding " << End << " avoided as " << BrokenPkg.FullName() << " has a pre-depends on " << Pkg.FullName() << std::endl;
+                       continue;
+                    }
+                    else
+                    {
+                       if (Debug)
+                       {
+                          clog << OutputInDepth(Depth) << "  Unpacking " << BrokenPkg.FullName() << " to avoid " << End;
+                          if (PkgLoop == true)
+                             clog << " (Looping)";
+                          clog << std::endl;
+                       }
+                       if (PkgLoop == false)
+                          List->Flag(Pkg,pkgOrderList::Loop);
+                       if (SmartUnPack(BrokenPkg, false, Depth + 1) == true)
+                       {
+                          if (List->IsFlag(BrokenPkg,pkgOrderList::Loop) == false)
+                             Changed = true;
+                       }
+                       if (PkgLoop == false)
+                          List->RmFlag(Pkg,pkgOrderList::Loop);
+                    }
+                 }
+              }
+              // Check if a package needs to be removed
+              else if (Cache[BrokenPkg].Delete() == true && List->IsFlag(BrokenPkg,pkgOrderList::Configured) == false)
+              {
+                 if (Debug)
+                    clog << OutputInDepth(Depth) << "  Removing " << BrokenPkg.FullName() << " to avoid " << End << endl;
+                 SmartRemove(BrokenPkg);
+              }
            }
         }
       }
-   }
+   } while (Changed == true);
    
    // Check for reverse conflicts.
    if (CheckRConflicts(Pkg,Pkg.RevDependsList(),
@@ -787,7 +878,7 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate, int c
       // Perform immedate configuration of the package. 
          if (SmartConfigure(Pkg, Depth + 1) == false)
             _error->Warning(_("Could not perform immediate configuration on '%s'. "
-               "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.Name(),2);
+               "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.FullName().c_str(),2);
    }
    
    return true;
@@ -827,11 +918,11 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall()
       {
          if (!List->IsFlag(Pkg,pkgOrderList::Configured) && !NoImmConfigure) {
             if (SmartConfigure(Pkg, 0) == false && Debug)
-               _error->Warning("Internal Error, Could not configure %s",Pkg.Name());
+               _error->Warning("Internal Error, Could not configure %s",Pkg.FullName().c_str());
             // FIXME: The above warning message might need changing
          } else {
            if (Debug == true)
-              clog << "Skipping already done " << Pkg.Name() << endl;
+              clog << "Skipping already done " << Pkg.FullName() << endl;
         }
         continue;
         
@@ -840,7 +931,7 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall()
       if (List->IsMissing(Pkg) == true)
       {
         if (Debug == true)
-           clog << "Sequence completed at " << Pkg.Name() << endl;
+           clog << "Sequence completed at " << Pkg.FullName() << endl;
         if (DoneSomething == false)
         {
            _error->Error("Internal Error, ordering was unable to handle the media swap");
@@ -854,7 +945,7 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall()
          Pkg.State() == pkgCache::PkgIterator::NeedsNothing &&
          (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)
       {
-        _error->Error("Internal Error, trying to manipulate a kept package (%s)",Pkg.Name());
+        _error->Error("Internal Error, trying to manipulate a kept package (%s)",Pkg.FullName().c_str());
         return Failed;
       }
       
@@ -887,7 +978,7 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall()
       if (List->IsFlag(*I,pkgOrderList::Configured) == false)
       {
         _error->Error("Internal error, packages left unconfigured. %s",
-                      PkgIterator(Cache,*I).Name());
+                      PkgIterator(Cache,*I).FullName().c_str());
         return Failed;
       }
    }
index c5b3bebd70ba5e2f3f6a4782c60eec3d2717889d..36dab3480d684cc87fef656ad46b15bd83bd04b4 100644 (file)
@@ -22,7 +22,7 @@
 // Records::pkgRecords - Constructor                                   /*{{{*/
 // ---------------------------------------------------------------------
 /* This will create the necessary structures to access the status files */
-pkgRecords::pkgRecords(pkgCache &Cache) : Cache(Cache), 
+pkgRecords::pkgRecords(pkgCache &Cache) : d(NULL), Cache(Cache),
   Files(Cache.HeaderP->PackageFileCount)
 {
    for (pkgCache::PkgFileIterator I = Cache.FileBegin();
index f61c140facec1926a4f27a472b1866ac824abdee..05ba6e0e69d13219689fe675b315bde97a7c1ee3 100644 (file)
@@ -26,11 +26,11 @@ unsigned long pkgSystem::GlobalListLen = 0;
 // System::pkgSystem - Constructor                                     /*{{{*/
 // ---------------------------------------------------------------------
 /* Add it to the global list.. */
-pkgSystem::pkgSystem()
+pkgSystem::pkgSystem() : Label(NULL), VS(NULL)
 {
    assert(GlobalListLen < sizeof(SysList)/sizeof(*SysList));
    SysList[GlobalListLen] = this;
-   GlobalListLen++;
+   ++GlobalListLen;
 }
                                                                        /*}}}*/
 // System::GetSystem - Get the named system                            /*{{{*/
index f5f458099f9098858967291032d69b4d9d3162e1..0fddfb45134ada915dfd445c5aa5e5ec4c132ded 100644 (file)
@@ -33,7 +33,7 @@ unsigned long pkgSourceList::Type::GlobalListLen = 0;
 // Type::Type - Constructor                                            /*{{{*/
 // ---------------------------------------------------------------------
 /* Link this to the global list of items*/
-pkgSourceList::Type::Type()
+pkgSourceList::Type::Type() : Name(NULL), Label(NULL)
 {
    ItmList[GlobalListLen] = this;
    GlobalListLen++;
index 48b643eace605c009781050125fdb965ed0a3891..d63d2c422b64b65b7d2acf233740ec113f818fd8 100644 (file)
@@ -25,7 +25,7 @@
 // SrcRecords::pkgSrcRecords - Constructor                             /*{{{*/
 // ---------------------------------------------------------------------
 /* Open all the source index files */
-pkgSrcRecords::pkgSrcRecords(pkgSourceList &List) : Files(0), Current(0)
+pkgSrcRecords::pkgSrcRecords(pkgSourceList &List) : d(NULL), Files(0), Current(0)
 {
    for (pkgSourceList::const_iterator I = List.begin(); I != List.end(); ++I)
    {
index ec86173df5fffb3db66117ebb6167e98086bb69b..79811899a9f6987567cc9113a141eeadeac9cee1 100644 (file)
@@ -30,7 +30,10 @@ using std::string;
 class pkgTagFilePrivate
 {
 public:
-   pkgTagFilePrivate(FileFd *pFd, unsigned long long Size) : Fd(*pFd), Size(Size)
+   pkgTagFilePrivate(FileFd *pFd, unsigned long long Size) : Fd(*pFd), Buffer(NULL),
+                                                            Start(NULL), End(NULL),
+                                                            Done(false), iOffset(0),
+                                                            Size(Size)
    {
    }
    FileFd &Fd;
index a9d4fb763d12c0fc15e7645b7dfc1217fa17ad4f..cb2c34c0fde1699dd02a801f1af56d7f7cec9432 100644 (file)
@@ -23,10 +23,10 @@ unsigned long pkgVersioningSystem::GlobalListLen = 0;
 // pkgVS::pkgVersioningSystem - Constructor                            /*{{{*/
 // ---------------------------------------------------------------------
 /* Link to the global list of versioning systems supported */
-pkgVersioningSystem::pkgVersioningSystem()
+pkgVersioningSystem::pkgVersioningSystem() : Label(NULL)
 {
    VSList[GlobalListLen] = this;
-   GlobalListLen++;
+   ++GlobalListLen;
 }
                                                                        /*}}}*/
 // pkgVS::GetVS - Find a VS by name                                    /*{{{*/
index 1ccb088040ff01e262039a12839c38fa287d6211..3ac350acab8d64124d71553192818af8e55f764f 100644 (file)
@@ -31,8 +31,9 @@ using namespace std;
 // ---------------------------------------------------------------------
 /* */
 AcqTextStatus::AcqTextStatus(unsigned int &ScreenWidth,unsigned int Quiet) :
-    ScreenWidth(ScreenWidth), Quiet(Quiet)
+    ScreenWidth(ScreenWidth), ID(0), Quiet(Quiet)
 {
+   BlankLine[0] = 0;
 }
                                                                        /*}}}*/
 // AcqTextStatus::Start - Downloading has started                      /*{{{*/
index 1cd5080cc44214504a3d46fb3c7036e778a977e7..94654ffd4c8864cd5227aa064f7bfa660fe17193 100644 (file)
@@ -1739,7 +1739,7 @@ int main(int argc,const char *argv[])                                     /*{{{*/
       {'c',"config-file",0,CommandLine::ConfigFile},
       {'o',"option",0,CommandLine::ArbItem},
       {0,"installed","APT::Cache::Installed",0},
-      {0,"pre-depends","APT::Cache::ShowPreDepends",0},
+      {0,"pre-depends","APT::Cache::ShowPre-Depends",0},
       {0,"depends","APT::Cache::ShowDepends",0},
       {0,"recommends","APT::Cache::ShowRecommends",0},
       {0,"suggests","APT::Cache::ShowSuggests",0},
index fa48debcdef9cff0a4820e36e8eeb5517b960535..0017d954e874e3ae293f54ef790b34f7bc2c3662 100644 (file)
@@ -150,10 +150,9 @@ bool DoAdd(CommandLine &)
    bool res = true;
 
    bool AutoDetect = _config->FindB("Acquire::cdrom::AutoDetect", true);
-   unsigned int count = 0;
-   
    if (AutoDetect && UdevCdroms.Dlopen())
    {
+      unsigned int count = 0;
       while (AutoDetectCdrom(UdevCdroms, count))
         res &= cdrom.Add(&log);
    } else {
@@ -178,10 +177,10 @@ bool DoIdent(CommandLine &)
    bool res = true;
 
    bool AutoDetect = _config->FindB("Acquire::cdrom::AutoDetect");
-   unsigned int count = 0;
-   
+
    if (AutoDetect && UdevCdroms.Dlopen())
    {
+      unsigned int count = 0;
       while (AutoDetectCdrom(UdevCdroms, count))
         res &= cdrom.Ident(ident, &log);
    } else {
index d5c1a3208db11c0a7d7b78bc1bad75fc450d4c38..dc4c110a122fbbd0261c808f8039bd7c4325f14b 100644 (file)
@@ -53,8 +53,8 @@ pkgCache *DebFile::Cache = 0;
 // ---------------------------------------------------------------------
 /* */
 DebFile::DebFile(const char *debfile)
-       : File(debfile, FileFd::ReadOnly), Control(0), DepOp(0), 
-          PreDepOp(0), Config(0), Template(0), Which(None)
+       : File(debfile, FileFd::ReadOnly), Size(0), Control(NULL), ControlLen(0),
+         DepOp(0), PreDepOp(0), Config(0), Template(0), Which(None)
 {
 }
                                                                        /*}}}*/
index 32ee469802ad2814b2b1b9b3595cd5e50777348c..f4ad75d1c5ba4a820d7a752e9cd3cc5c4cfe1973 100644 (file)
@@ -713,11 +713,32 @@ public:
        }
 
        virtual pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
-               APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, APT::VersionSet::NEWEST);
-               if (verset.empty() == false)
-                       return *(verset.begin());
-               if (ShowError == true)
-                       ioprintf(out, _("Virtual packages like '%s' can't be removed\n"), Pkg.FullName(true).c_str());
+               if (Pkg->ProvidesList != 0)
+               {
+                       APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, APT::VersionSet::NEWEST);
+                       if (verset.empty() == false)
+                               return *(verset.begin());
+                       if (ShowError == true)
+                               ioprintf(out, _("Virtual packages like '%s' can't be removed\n"), Pkg.FullName(true).c_str());
+               }
+               else
+               {
+                       pkgCache::GrpIterator Grp = Pkg.Group();
+                       pkgCache::PkgIterator P = Grp.PackageList();
+                       for (; P.end() != true; P = Grp.NextPkg(P))
+                       {
+                               if (P == Pkg)
+                                       continue;
+                               if (P->CurrentVer != 0) {
+                                       // TRANSLATORS: Note, this is not an interactive question
+                                       ioprintf(c1out,_("Package '%s' is not installed, so not removed. Did you mean '%s'?\n"),
+                                                Pkg.FullName(true).c_str(), P.FullName(true).c_str());
+                                       break;
+                               }
+                       }
+                       if (P.end() == true)
+                               ioprintf(c1out,_("Package '%s' is not installed, so not removed\n"),Pkg.FullName(true).c_str());
+               }
                return pkgCache::VerIterator(Cache, 0);
        }
 
@@ -904,7 +925,23 @@ struct TryToRemove {
       if ((Pkg->CurrentVer == 0 && PurgePkgs == false) ||
          (PurgePkgs == true && Pkg->CurrentState == pkgCache::State::NotInstalled))
       {
-        ioprintf(c1out,_("Package %s is not installed, so not removed\n"),Pkg.FullName(true).c_str());
+        pkgCache::GrpIterator Grp = Pkg.Group();
+        pkgCache::PkgIterator P = Grp.PackageList();
+        for (; P.end() != true; P = Grp.NextPkg(P))
+        {
+           if (P == Pkg)
+              continue;
+           if (P->CurrentVer != 0 || (PurgePkgs == true && P->CurrentState != pkgCache::State::NotInstalled))
+           {
+              // TRANSLATORS: Note, this is not an interactive question
+              ioprintf(c1out,_("Package '%s' is not installed, so not removed. Did you mean '%s'?\n"),
+                       Pkg.FullName(true).c_str(), P.FullName(true).c_str());
+              break;
+           }
+        }
+        if (P.end() == true)
+           ioprintf(c1out,_("Package '%s' is not installed, so not removed\n"),Pkg.FullName(true).c_str());
+
         // MarkInstall refuses to install packages on hold
         Pkg->SelectedState = pkgCache::State::Hold;
       }
index c7d9b6f6aeb06db4f03a0dd9a093381810103bc8..ef43317142210573455bc40aff6b6a0f2df70c50 100644 (file)
 #include <apt-pkg/init.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/pkgsystem.h>
+#include <apt-pkg/fileutl.h>
 
 #include <algorithm>
+#include <errno.h>
 #include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <fcntl.h>
 
 #include <apti18n.h>
                                                                        /*}}}*/
@@ -158,13 +164,63 @@ bool DoHold(CommandLine &CmdL)
    if (unlikely(Cache == NULL))
       return false;
 
+   // Generate the base argument list for dpkg
+   std::vector<const char *> Args;
+   string Tmp = _config->Find("Dir::Bin::dpkg","dpkg");
+   {
+      string const dpkgChrootDir = _config->FindDir("DPkg::Chroot-Directory", "/");
+      size_t dpkgChrootLen = dpkgChrootDir.length();
+      if (dpkgChrootDir != "/" && Tmp.find(dpkgChrootDir) == 0)
+      {
+        if (dpkgChrootDir[dpkgChrootLen - 1] == '/')
+           --dpkgChrootLen;
+        Tmp = Tmp.substr(dpkgChrootLen);
+      }
+   }
+   Args.push_back(Tmp.c_str());
+
+   // Stick in any custom dpkg options
+   Configuration::Item const *Opts = _config->Tree("DPkg::Options");
+   if (Opts != 0)
+   {
+      Opts = Opts->Child;
+      for (; Opts != 0; Opts = Opts->Next)
+      {
+        if (Opts->Value.empty() == true)
+           continue;
+        Args.push_back(Opts->Value.c_str());
+      }
+   }
+
+   size_t const BaseArgs = Args.size();
+   // we need to detect if we can qualify packages with the architecture or not
+   Args.push_back("--assert-multi-arch");
+   Args.push_back(NULL);
+
+
+   pid_t dpkgAssertMultiArch = ExecFork();
+   if (dpkgAssertMultiArch == 0)
+   {
+      std::string const chrootDir = _config->FindDir("DPkg::Chroot-Directory");
+      if (chrootDir != "/" && chroot(chrootDir.c_str()) != 0)
+        _error->WarningE("getArchitecture", "Couldn't chroot into %s for dpkg --assert-multi-arch", chrootDir.c_str());
+      // redirect everything to the ultimate sink as we only need the exit-status
+      int const nullfd = open("/dev/null", O_RDONLY);
+      dup2(nullfd, STDIN_FILENO);
+      dup2(nullfd, STDOUT_FILENO);
+      dup2(nullfd, STDERR_FILENO);
+      execvp(Args[0], (char**) &Args[0]);
+      _error->WarningE("dpkgGo", "Can't detect if dpkg supports multi-arch!");
+      _exit(2);
+   }
+
    APT::PackageList pkgset = APT::PackageList::FromCommandLine(CacheFile, CmdL.FileList + 1);
    if (pkgset.empty() == true)
       return _error->Error(_("No packages found"));
 
    bool const MarkHold = strcasecmp(CmdL.FileList[0],"hold") == 0;
 
-   for (APT::PackageList::iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
+   for (APT::PackageList::iterator Pkg = pkgset.begin(); Pkg != pkgset.end();)
    {
       if ((Pkg->SelectedState == pkgCache::State::Hold) == MarkHold)
       {
@@ -172,9 +228,25 @@ bool DoHold(CommandLine &CmdL)
            ioprintf(c1out,_("%s was already set on hold.\n"), Pkg.FullName(true).c_str());
         else
            ioprintf(c1out,_("%s was already not hold.\n"), Pkg.FullName(true).c_str());
-        pkgset.erase(Pkg);
-        continue;
+        Pkg = pkgset.erase(Pkg, true);
+      }
+      else
+        ++Pkg;
+   }
+
+   bool dpkgMultiArch = false;
+   if (dpkgAssertMultiArch > 0)
+   {
+      int Status = 0;
+      while (waitpid(dpkgAssertMultiArch, &Status, 0) != dpkgAssertMultiArch)
+      {
+        if (errno == EINTR)
+           continue;
+        _error->WarningE("dpkgGo", _("Waited for %s but it wasn't there"), "dpkg --assert-multi-arch");
+        break;
       }
+      if (WIFEXITED(Status) == true && WEXITSTATUS(Status) == 0)
+        dpkgMultiArch = true;
    }
 
    if (pkgset.empty() == true)
@@ -192,36 +264,60 @@ bool DoHold(CommandLine &CmdL)
       return true;
    }
 
-   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(" --set-selections");
-   FILE *dpkg = popen(dpkgcall.c_str(), "w");
-   if (dpkg == NULL)
-      return _error->Errno("DoHold", "fdopen on dpkg stdin failed");
+   Args.erase(Args.begin() + BaseArgs, Args.end());
+   Args.push_back("--set-selections");
+   Args.push_back(NULL);
+
+   int external[2] = {-1, -1};
+   if (pipe(external) != 0)
+      return _error->WarningE("DoHold", "Can't create IPC pipe for dpkg --set-selections");
 
+   pid_t dpkgSelection = ExecFork();
+   if (dpkgSelection == 0)
+   {
+      close(external[1]);
+      std::string const chrootDir = _config->FindDir("DPkg::Chroot-Directory");
+      if (chrootDir != "/" && chroot(chrootDir.c_str()) != 0)
+        _error->WarningE("getArchitecture", "Couldn't chroot into %s for dpkg --set-selections", chrootDir.c_str());
+      int const nullfd = open("/dev/null", O_RDONLY);
+      dup2(external[0], STDIN_FILENO);
+      dup2(nullfd, STDOUT_FILENO);
+      dup2(nullfd, STDERR_FILENO);
+      execvp(Args[0], (char**) &Args[0]);
+      _error->WarningE("dpkgGo", "Can't detect if dpkg supports multi-arch!");
+      _exit(2);
+   }
+
+   FILE* dpkg = fdopen(external[1], "w");
    for (APT::PackageList::iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
    {
       if (MarkHold == true)
       {
-        fprintf(dpkg, "%s hold\n", Pkg.FullName(true).c_str());
+        fprintf(dpkg, "%s hold\n", Pkg.FullName(!dpkgMultiArch).c_str());
         ioprintf(c1out,_("%s set on hold.\n"), Pkg.FullName(true).c_str());
       }
       else
       {
-        fprintf(dpkg, "%s install\n", Pkg.FullName(true).c_str());
+        fprintf(dpkg, "%s install\n", Pkg.FullName(!dpkgMultiArch).c_str());
         ioprintf(c1out,_("Canceled hold on %s.\n"), Pkg.FullName(true).c_str());
       }
    }
+   fclose(dpkg);
 
-   int const status = pclose(dpkg);
-   if (status == -1)
-      return _error->Errno("DoHold", "dpkg execution failed in the end");
-   if (WIFEXITED(status) == false || WEXITSTATUS(status) != 0)
-      return _error->Error(_("Executing dpkg failed. Are you root?"));
-   return true;
+   if (dpkgSelection > 0)
+   {
+      int Status = 0;
+      while (waitpid(dpkgSelection, &Status, 0) != dpkgSelection)
+      {
+        if (errno == EINTR)
+           continue;
+        _error->WarningE("dpkgGo", _("Waited for %s but it wasn't there"), "dpkg --set-selection");
+        break;
+      }
+      if (WIFEXITED(Status) == true && WEXITSTATUS(Status) == 0)
+        return true;
+   }
+   return _error->Error(_("Executing dpkg failed. Are you root?"));
 }
                                                                        /*}}}*/
 /* ShowHold - show packages set on hold in dpkg status                 {{{*/
index 25563e811c763f0a19af257e390f67c156c67648..32b271668f457276c633fd0d050ee68949db292e 100644 (file)
@@ -1,9 +1,34 @@
-apt (0.8.16~exp13) UNRELEASED; urgency=low
+apt (0.8.16~exp14) UNRELEASED; urgency=low
+
+  [ Michael Vogt ]
+  * apt-pkg/packagemanager.cc:
+    - fix inconsistent clog/cout usage in the debug output
+  
+  [ David Kalnischkies ]
+  * apt-pkg/packagemanager.cc:
+    - recheck all dependencies if we changed a package in SmartConfigure
+      as this could break an earlier dependency (LP: #940396)
+    - recheck dependencies in SmartUnpack after a change, too
+
+ -- David Kalnischkies <kalnischkies@gmail.com>  Tue, 13 Mar 2012 12:38:35 +0100
+
+apt (0.8.16~exp13) experimental; urgency=low
 
   [ David Kalnischkies ]
+  * apt-pkg/acquire-item.cc:
+    - remove 'old' InRelease file if we can't get a new one before
+      proceeding with Release.gpg to avoid the false impression of a still
+      trusted repository by a (still present) old InRelease file.
+      Thanks to Simon Ruderich for reporting this issue! (CVE-2012-0214)
+    - add Debug::pkgAcqArchive::NoQueue to disable package downloading
   * apt-pkg/deb/dpkgpm.cc:
     - chroot if needed before dpkg --assert-multi-arch
     - ensure that dpkg binary doesn't have the chroot-directory prefixed
+    - call dpkg --assert-multi-arch with execvp instead of execv
+    - save the universe by not printing messages about apport if a package
+      with this name is not installed (Closes: #619646)
+    - handle a SIGINT in all modes as a break after the currently running
+      dpkg transaction instead of ignoring it completely
   * apt-pkg/depcache.cc:
     - if a M-A:same package is marked for reinstall, mark all it's installed
       silbings for reinstallation as well (LP: #859188)
@@ -13,8 +38,35 @@ apt (0.8.16~exp13) UNRELEASED; urgency=low
     - if a file without an extension is requested send an 'Accept: text/*'
       header to avoid that the server chooses unsupported compressed files
       in a content-negotation attempt (Closes: #657560)
+    - remove the arbitrary MAXLEN limit for response lines (Closes: #658346)
   * apt-pkg/aptconfiguration.cc:
     - chroot if needed before calling dpkg --print-foreign-architectures
+    - ensure that architectures are not added multiple times
+  * cmdline/apt-mark.cc:
+    - detect if dpkg has multiarch support before calling --set-selections
+    - correctly ignore already (un)hold packages
+  * apt-pkg/cachefile.cc:
+    - clean up lost atomic cachefiles with 'clean' (Closes: #650513)
+  * apt-pkg/indexrecords.cc:
+    - do not create empty Entries as a sideeffect of Lookup()
+  * apt-pkg/acquire-item.cc:
+    - drop support for i18n/Index file (introduced in 0.8.11) and use
+      the Release file instead to get the Translations (Closes: #649314)
+    - use pdiff for Translation-* files if available (Closes: #657902)
+  * ftparchive/writer.cc:
+    - add 'Translation-*' to the default patterns
+  * cmdline/apt-get.cc:
+    - if a package can't be removed as it is not installed, suggest to
+      the user an (installed) multiarch silbing with 'Did you mean?'
+    - improve 'error' message for packages which are only referenced
+      e.g. in a Depends line and are now requested for removal
+  * cmdline/apt-cache.cc:
+    - correct --pre-depends option by using dash consistently (LP: #940837)
+  * apt-pkg/packagemanager.cc:
+    - do not try to a void a breaks if the broken package pre-depends
+      on the breaker, but let dpkg auto-deconfigure it
+  * apt-pkg/contrib/fileutl.cc:
+    - do not warn about the ignoring of directories (Closes: #662762)
 
   [ Steve Langasek ]
   * cmdline/apt-get.cc:
@@ -27,7 +79,9 @@ apt (0.8.16~exp13) UNRELEASED; urgency=low
       of them in a single iteration (Closes: #657695, LP: #922485)
     - use a signed int instead of short for score calculation as upgrades
       become so big now that it can overflow (Closes: #657732, LP: #917173)
-  
+  * Fix IndexCopy::CopyPackages and TranslationsCopy::CopyTranslations to
+    handle compressed files again (LP: #924182, closes: #658096)
+
   [ Michael Vogt ]
   * apt-pkg/deb/dpkgpm.cc:
     - fix crash when a package is in removed but residual config state
@@ -35,10 +89,20 @@ apt (0.8.16~exp13) UNRELEASED; urgency=low
   * apt-pkg/contrib/fileutl.h:
     - fix compat with FileFd::OpenDescriptor() in ReadOnlyGzip mode
   * apt-pkg/packagemanager.cc:
-    - when calculating pre-dependencies ensure that both unpack and
-      configure are considered (instead of only configure) LP: #927993
+    - fix bug in predepends handling - ensure that packages that needs
+      unpackaging are unpacked before they are configured (LP: #927993)
+
+  [ Julian Andres Klode ]
+  * apt-pkg/deb/deblistparser.cc:
+    - Set the Essential flag on APT instead of only Important
+  * apt-pkg/packagemanager.cc:
+    - Do not use immediate configuration for packages with the Important flag
+  * Treat the Important flag like the Essential flag with those differences:
+    - No Immediate configuration (see above)
+    - Not automatically installed during dist-upgrade
+    - No higher score for installation ordering
 
- -- David Kalnischkies <kalnischkies@gmail.com>  Mon, 30 Jan 2012 19:17:09 +0100
+ -- Michael Vogt <mvo@debian.org>  Tue, 06 Mar 2012 18:12:57 +0100
 
 apt (0.8.16~exp12) experimental; urgency=low
 
index 377c4160728463117402a9c2f85f9ce1e82903a6..b9ced941843e5e17b3dd6d95a46e45730ee1683d 100644 (file)
@@ -126,7 +126,8 @@ class CacheDB
          Misses += S.Misses; 
          DeLinkBytes += S.DeLinkBytes;
       };
-      Stats() : Bytes(0), MD5Bytes(0), SHA1Bytes(0), SHA256Bytes(0), Packages(0), Misses(0), DeLinkBytes(0) {};
+      Stats() : Bytes(0), MD5Bytes(0), SHA1Bytes(0), SHA256Bytes(0),
+               SHA512Bytes(0),Packages(0), Misses(0), DeLinkBytes(0) {};
    } Stats;
    
    bool ReadyDB(std::string const &DB);
@@ -142,7 +143,7 @@ class CacheDB
    
    bool Clean();
    
-   CacheDB(std::string const &DB) : Dbp(0), Fd(NULL), DebFile(0) {ReadyDB(DB);};
+   CacheDB(std::string const &DB) : Dbp(0), Fd(NULL), DebFile(0) {TmpKey[0]='\0'; ReadyDB(DB);};
    ~CacheDB() {ReadyDB(std::string()); delete DebFile;};
 };
     
index 159772991eca6f6320f74ba17dbc7b50c8f0310f..d02919969da6aeaa5739ad911177d81e8a6bd017 100644 (file)
@@ -941,6 +941,7 @@ ReleaseWriter::ReleaseWriter(string const &DB)
       AddPattern("Packages.bz2");
       AddPattern("Packages.lzma");
       AddPattern("Packages.xz");
+      AddPattern("Translation-*");
       AddPattern("Sources");
       AddPattern("Sources.gz");
       AddPattern("Sources.bz2");
index ad8a7b828a2ce0563014fb6591a9641061cafbd3..d55ac1224de05612096522ad575c1a926ef3139c 100644 (file)
@@ -77,6 +77,7 @@ FTPConn::FTPConn(URI Srv) : Len(0), ServerFd(-1), DataFd(-1),
 {
    Debug = _config->FindB("Debug::Acquire::Ftp",false);
    PasvAddr = 0;
+   Buffer[0] = '\0';
 }
                                                                        /*}}}*/
 // FTPConn::~FTPConn - Destructor                                      /*{{{*/
@@ -621,8 +622,7 @@ bool FTPConn::ExtGoPasv()
    }
    
    // Get a new passive address.
-   int Res;
-   if ((Res = getaddrinfo(IP.c_str(),PStr,&Hints,&PasvAddr)) != 0)
+   if (getaddrinfo(IP.c_str(),PStr,&Hints,&PasvAddr) != 0)
       return true;
    
    return true;
@@ -720,14 +720,13 @@ bool FTPConn::CreateDataFd()
    DataListenFd = -1;
 
    // Get the information for a listening socket.
-   struct addrinfo *BindAddr = 0;
+   struct addrinfo *BindAddr = NULL;
    struct addrinfo Hints;
    memset(&Hints,0,sizeof(Hints));
    Hints.ai_socktype = SOCK_STREAM;
    Hints.ai_flags |= AI_PASSIVE;
    Hints.ai_family = ((struct sockaddr *)&ServerAddr)->sa_family;
-   int Res;
-   if ((Res = getaddrinfo(0,"0",&Hints,&BindAddr)) != 0)
+   if (getaddrinfo(0,"0",&Hints,&BindAddr) != 0 || BindAddr == NULL)
       return _error->Error(_("getaddrinfo was unable to get a listening socket"));
    
    // Construct the socket
index 2721b1224e69afd8025aff8b514e4d110c9abc43..d2e03cfbc13352c295e13080d38c3f20a8beed73 100644 (file)
@@ -42,6 +42,7 @@
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
+#include <climits>
 #include <iostream>
 #include <map>
 
@@ -534,10 +535,6 @@ bool ServerState::HeaderLine(string Line)
    if (Line.empty() == true)
       return true;
 
-   // The http server might be trying to do something evil.
-   if (Line.length() >= MAXLEN)
-      return _error->Error(_("Got a single header line over %u chars"),MAXLEN);
-
    string::size_type Pos = Line.find(' ');
    if (Pos == string::npos || Pos+1 > Line.length())
    {
@@ -561,7 +558,7 @@ bool ServerState::HeaderLine(string Line)
       // Evil servers return no version
       if (Line[4] == '/')
       {
-        int const elements = sscanf(Line.c_str(),"HTTP/%u.%u %u%[^\n]",&Major,&Minor,&Result,Code);
+        int const elements = sscanf(Line.c_str(),"HTTP/%3u.%3u %3u%359[^\n]",&Major,&Minor,&Result,Code);
         if (elements == 3)
         {
            Code[0] = '\0';
@@ -575,7 +572,7 @@ bool ServerState::HeaderLine(string Line)
       {
         Major = 0;
         Minor = 9;
-        if (sscanf(Line.c_str(),"HTTP %u%[^\n]",&Result,Code) != 2)
+        if (sscanf(Line.c_str(),"HTTP %3u%359[^\n]",&Result,Code) != 2)
            return _error->Error(_("The HTTP server sent an invalid reply header"));
       }
 
@@ -585,7 +582,7 @@ bool ServerState::HeaderLine(string Line)
         Persistent = false;
       else
       {
-        if (Major == 1 && Minor <= 0)
+        if (Major == 1 && Minor == 0)
            Persistent = false;
         else
            Persistent = true;
@@ -603,9 +600,10 @@ bool ServerState::HeaderLine(string Line)
       // The length is already set from the Content-Range header
       if (StartPos != 0)
         return true;
-      
-      if (sscanf(Val.c_str(),"%llu",&Size) != 1)
-        return _error->Error(_("The HTTP server sent an invalid Content-Length header"));
+
+      Size = strtoull(Val.c_str(), NULL, 10);
+      if (Size == ULLONG_MAX)
+        return _error->Errno("HeaderLine", _("The HTTP server sent an invalid Content-Length header"));
       return true;
    }
 
@@ -1329,7 +1327,7 @@ int HttpMethod::Loop()
                after the same URI is seen twice in a queue item. */
             StringVector &R = Redirected[Queue->DestFile];
             bool StopRedirects = false;
-            if (R.size() == 0)
+            if (R.empty() == true)
                R.push_back(Queue->Uri);
             else if (R[0] == "STOP" || R.size() > 10)
                StopRedirects = true;
index c73d4df5ca5252d159ce7fd9c03ddcbc25b80f64..7a3ccda5407bc32ddb368ae2cb962fd6492577ec 100644 (file)
@@ -11,8 +11,6 @@
 #ifndef APT_HTTP_H
 #define APT_HTTP_H
 
-#define MAXLEN 360
-
 #include <apt-pkg/strutl.h>
 
 #include <string>
@@ -92,7 +90,7 @@ struct ServerState
    unsigned int Major;
    unsigned int Minor;
    unsigned int Result;
-   char Code[MAXLEN];
+   char Code[360];
    
    // These are some statistics from the last parsed header lines
    unsigned long long Size;
@@ -117,9 +115,10 @@ struct ServerState
   
    bool HeaderLine(std::string Line);
    bool Comp(URI Other) const {return Other.Host == ServerName.Host && Other.Port == ServerName.Port;};
-   void Reset() {Major = 0; Minor = 0; Result = 0; Size = 0; StartPos = 0;
-                 Encoding = Closes; time(&Date); ServerFd = -1; 
-                 Pipeline = true;};
+   void Reset() {Major = 0; Minor = 0; Result = 0; Code[0] = '\0'; Size = 0;
+                StartPos = 0; Encoding = Closes; time(&Date); HaveContent = false;
+                State = Header; Persistent = false; ServerFd = -1;
+                Pipeline = true;};
 
    /** \brief Result of the header acquire */
    enum RunHeadersResult {
index b7adeb88084f32bb762796a318e8227960195178..b1961a8706f4043cacbe31f4fc5d20912e3b987e 100644 (file)
@@ -8,10 +8,8 @@
    ##################################################################### */
                                                                        /*}}}*/
 
-#ifndef APT_HTTP_H
-#define APT_HTTP_H
-
-#define MAXLEN 360
+#ifndef APT_HTTPS_H
+#define APT_HTTPS_H
 
 #include <iostream>
 #include <curl/curl.h>
index 3d5983efa59a49b3d7b67b633daadedb923ded50..3b2ab8ede38cf2c761bec7e7e37774b903d0b671 100644 (file)
@@ -147,7 +147,7 @@ bool MirrorMethod::DownloadMirrorFile(string mirror_uri_str)
    // append all architectures
    std::vector<std::string> vec = APT::Configuration::getArchitectures();
    for (std::vector<std::string>::const_iterator I = vec.begin();
-        I != vec.end(); I++)
+        I != vec.end(); ++I)
       if (I == vec.begin())
          fetch += "?arch" + (*I);
       else
index d249ae96102aa456e69faa60fb83ea26f43035d6..fb3782314d2152bd4e2378fda6178b04581b2d9b 100644 (file)
@@ -42,7 +42,9 @@ int RSHMethod::FailFd = -1;
 // ---------------------------------------------------------------------
 /* */
 RSHConn::RSHConn(URI Srv) : Len(0), WriteFd(-1), ReadFd(-1),
-                            ServerName(Srv), Process(-1) {}
+                            ServerName(Srv), Process(-1) {
+   Buffer[0] = '\0';
+}
                                                                        /*}}}*/
 // RSHConn::RSHConn - Destructor                                       /*{{{*/
 // ---------------------------------------------------------------------
diff --git a/test/integration/Packages-bug-64141-install-dependencies-for-on-hold b/test/integration/Packages-bug-64141-install-dependencies-for-on-hold
deleted file mode 100644 (file)
index 7005fa4..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-Package: apt
-Priority: important
-Section: admin
-Installed-Size: 6048
-Maintainer: APT Development Team <deity@lists.debian.org>
-Architecture: i386
-Version: 0.8.10
-Provides: libapt-pkg4.10
-Depends: libc6 (>= 2.10), libdb4.8
-Breaks: oldcrap
-Filename: pool/main/a/apt/apt_0.8.10_i386.deb
-Size: 2160758
-MD5sum: 5aa2234f7b91056d430669cddf6e6e50
-Description: Advanced front-end for dpkg
-
-Package: libc6
-Priority: required
-Section: libs
-Installed-Size: 9356
-Maintainer: GNU Libc Maintainers <debian-glibc@lists.debian.org>
-Architecture: i386
-Source: eglibc
-Version: 2.11.2-7
-Provides: glibc-2.11-1
-Filename: pool/main/e/eglibc/libc6_2.11.2-7_i386.deb
-Size: 3880868
-MD5sum: c48fd2854fc62125824267d086600793
-Description: Embedded GNU C Library: Shared libraries
-
-Package: libdb4.8
-Priority: standard
-Section: libs
-Installed-Size: 1488
-Maintainer: Clint Adams <clint@gnu.org>
-Architecture: i386
-Source: db4.8
-Version: 4.8.30-3
-Depends: libc6 (>= 2.3.6-6~)
-Filename: pool/main/d/db4.8/libdb4.8_4.8.30-3_i386.deb
-Size: 681988
-MD5sum: 0d58c15898a95436d2ec480aa22693ff
-Description: Berkeley v4.8 Database Libraries [runtime]
index d7526a100b5f0fac448805e3d7eed1331fdb3bd4..a738d27ccb4f610cb01710653ee2c00616cd63fd 100644 (file)
@@ -29,7 +29,8 @@ msgtest() {
        while [ -n "$1" ]; do
                echo -n "${CINFO}$1${CCMD} " >&2;
                echo -n "$(echo "$2" | sed -e 's/^aptc/apt-c/' -e 's/^aptg/apt-g/' -e 's/^aptf/apt-f/')${CINFO} " >&2;
-               shift 2
+               shift
+               if [ -n "$1" ]; then shift; else break; fi
        done
        echo -n "…${CNORMAL} " >&2;
 }
@@ -114,9 +115,9 @@ addtrap() {
 
 setupenvironment() {
        TMPWORKINGDIRECTORY=$(mktemp -d)
-       local TESTDIR=$(readlink -f $(dirname $0))
+       TESTDIRECTORY=$(readlink -f $(dirname $0))
        msgninfo "Preparing environment for ${CCMD}$(basename $0)${CINFO} in ${TMPWORKINGDIRECTORY}… "
-       BUILDDIRECTORY="${TESTDIR}/../../build/bin"
+       BUILDDIRECTORY="${TESTDIRECTORY}/../../build/bin"
        test -x "${BUILDDIRECTORY}/apt-get" || msgdie "You need to build tree first"
        local OLDWORKINGDIRECTORY=$(pwd)
        addtrap "cd /; rm -rf $TMPWORKINGDIRECTORY; cd $OLDWORKINGDIRECTORY;"
@@ -126,25 +127,19 @@ setupenvironment() {
        mkdir -p etc/apt/apt.conf.d etc/apt/sources.list.d etc/apt/trusted.gpg.d etc/apt/preferences.d
        mkdir -p var/cache var/lib var/log
        mkdir -p var/lib/dpkg/info var/lib/dpkg/updates var/lib/dpkg/triggers
-       local STATUSFILE=$(echo "$(basename $0)" | sed -e 's/^test-/status-/' -e 's/^skip-/status-/')
-       if [ -f "${TESTDIR}/${STATUSFILE}" ]; then
-               cp "${TESTDIR}/${STATUSFILE}" var/lib/dpkg/status
-       else
-               touch var/lib/dpkg/status
-       fi
        touch var/lib/dpkg/available
        mkdir -p usr/lib/apt
        ln -s ${BUILDDIRECTORY}/methods usr/lib/apt/methods
        cd ..
        local PACKAGESFILE=$(echo "$(basename $0)" | sed -e 's/^test-/Packages-/' -e 's/^skip-/Packages-/')
-       if [ -f "${TESTDIR}/${PACKAGESFILE}" ]; then
-               cp "${TESTDIR}/${PACKAGESFILE}" aptarchive/Packages
+       if [ -f "${TESTDIRECTORY}/${PACKAGESFILE}" ]; then
+               cp "${TESTDIRECTORY}/${PACKAGESFILE}" aptarchive/Packages
        fi
        local SOURCESSFILE=$(echo "$(basename $0)" | sed -e 's/^test-/Sources-/' -e 's/^skip-/Sources-/')
-       if [ -f "${TESTDIR}/${SOURCESSFILE}" ]; then
-               cp "${TESTDIR}/${SOURCESSFILE}" aptarchive/Sources
+       if [ -f "${TESTDIRECTORY}/${SOURCESSFILE}" ]; then
+               cp "${TESTDIRECTORY}/${SOURCESSFILE}" aptarchive/Sources
        fi
-       cp $(find $TESTDIR -name '*.pub' -o -name '*.sec') keys/
+       cp $(find $TESTDIRECTORY -name '*.pub' -o -name '*.sec') keys/
        ln -s ${TMPWORKINGDIRECTORY}/keys/joesixpack.pub rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
        echo "Dir \"${TMPWORKINGDIRECTORY}/rootdir\";" > aptconfig.conf
        echo "Dir::state::status \"${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status\";" >> aptconfig.conf
@@ -156,7 +151,9 @@ setupenvironment() {
        echo "DPKG::options:: \"--root=${TMPWORKINGDIRECTORY}/rootdir\";" >> aptconfig.conf
        echo "DPKG::options:: \"--force-not-root\";" >> aptconfig.conf
        echo "DPKG::options:: \"--force-bad-path\";" >> aptconfig.conf
-       echo "DPKG::options:: \"--force-architecture\";" >> aptconfig.conf # Added to test multiarch before dpkg is ready for it…
+       if ! $(which dpkg) --assert-multi-arch; then
+               echo "DPKG::options:: \"--force-architecture\";" >> aptconfig.conf # Added to test multiarch before dpkg is ready for it…
+       fi
        echo "DPKG::options:: \"--log=${TMPWORKINGDIRECTORY}/rootdir/var/log/dpkg.log\";" >> aptconfig.conf
        echo 'quiet::NoUpdate "true";' >> aptconfig.conf
        export LC_ALL=C
@@ -170,13 +167,17 @@ getarchitecture() {
                if [ -n "$ARCH" ]; then
                        echo $ARCH
                else
-                       dpkg-architecture -qDEB_BUILD_ARCH
+                       dpkg --print-architecture
                fi
        else
                echo $1
        fi
 }
 
+getarchitectures() {
+       echo "$(aptconfig dump | grep APT::Architecture | cut -d'"' -f 2 | sed '/^$/ d' | sort | uniq | tr '\n' ' ')"
+}
+
 configarchitecture() {
        local CONFFILE=rootdir/etc/apt/apt.conf.d/01multiarch.conf
        rm -f $CONFFILE
@@ -186,6 +187,30 @@ configarchitecture() {
                echo "APT::Architectures:: \"$(getarchitecture $1)\";" >> $CONFFILE
                shift
        done
+       configdpkg
+}
+
+configdpkg() {
+       if [ ! -e rootdir/var/lib/dpkg/status ]; then
+               local STATUSFILE=$(echo "$(basename $0)" | sed -e 's/^test-/status-/' -e 's/^skip-/status-/')
+               if [ -f "${TESTDIRECTORY}/${STATUSFILE}" ]; then
+                       cp "${TESTDIRECTORY}/${STATUSFILE}" rootdir/var/lib/dpkg/status
+               else
+                       echo -n > rootdir/var/lib/dpkg/status
+               fi
+       fi
+       if $(which dpkg) --assert-multi-arch; then
+               local ARCHS="$(getarchitectures)"
+               if echo "$ARCHS" | grep -E -q '[^ ]+ [^ ]+'; then
+                       DPKGARCH="$(dpkg --print-architecture)"
+                       for ARCH in ${ARCHS}; do
+                               if [ "${ARCH}" != "${DPKGARCH}" ]; then dpkg --add-architecture ${ARCH}; fi
+                       done
+                       if [ "0" = "$(dpkg -l dpkg 2> /dev/null | grep '^i' | wc -l)" ]; then
+                               insertinstalledpackage 'dpkg' "all" '1.16.2~wipmultiarch~fake'
+                       fi
+               fi
+       fi
 }
 
 setupsimplenativepackage() {
@@ -350,7 +375,7 @@ createaptftparchiveconfig() {
        local ARCHS="$(find pool/ -name '*.deb' | grep -oE '_[a-z0-9-]+\.deb$' | sort | uniq | sed -e '/^_all.deb$/ d' -e 's#^_\([a-z0-9-]*\)\.deb$#\1#' | tr '\n' ' ')"
        if [ -z "$ARCHS" ]; then
                # the pool is empty, so we will operate on faked packages - let us use the configured archs
-               ARCHS="$(aptconfig dump | grep APT::Architecture | cut -d'"' -f 2 | sed '/^$/ d' | sort | uniq | tr '\n' ' ')"
+               ARCHS="$(getarchitectures)"
        fi
        echo -n 'Dir {
        ArchiveDir "' >> ftparchive.conf
@@ -432,7 +457,7 @@ insertpackage() {
        local ARCHS=""
        for arch in $(echo "$ARCH" | sed -e 's#,#\n#g' | sed -e "s#^native\$#$(getarchitecture 'native')#"); do
                if [ "$arch" = "all" ]; then
-                       ARCHS="$(aptconfig dump | grep APT::Architecture | cut -d'"' -f 2 | sed '/^$/ d' | sort | uniq | tr '\n' ' ')"
+                       ARCHS="$(getarchitectures)"
                else
                        ARCHS="$arch"
                fi
@@ -486,7 +511,8 @@ insertinstalledpackage() {
        local VERSION="$3"
        local DEPENDENCIES="$4"
        local PRIORITY="${5:-optional}"
-       local FILE="rootdir/var/lib/dpkg/status"
+       local FILE='rootdir/var/lib/dpkg/status'
+       local INFO='rootdir/var/lib/dpkg/info'
        for arch in $(echo "$ARCH" | sed -e 's#,#\n#g' | sed -e "s#^native\$#$(getarchitecture 'native')#"); do
                echo "Package: $NAME
 Status: install ok installed
@@ -502,6 +528,11 @@ Version: $VERSION" >> $FILE
  YOU did something horribly wrong! They are autogenerated
  und used only by testcases for APT and surf no other propose…
 " >> $FILE
+               if [ "$(dpkg-query -W --showformat='${Multi-Arch}')" = 'same' ]; then
+                       echo -n > ${INFO}/${NAME}:${arch}.list
+               else
+                       echo -n > ${INFO}/${NAME}.list
+               fi
        done
 }
 
@@ -542,9 +573,6 @@ generatereleasefiles() {
        # both should be given in notation date/touch can understand
        msgninfo "\tGenerate Release files… "
        if [ -e aptarchive/dists ]; then
-               for dir in $(find ./aptarchive/dists -mindepth 3 -maxdepth 3 -type d -name 'i18n'); do
-                       aptftparchive -qq release $dir -o APT::FTPArchive::Release::Patterns::='Translation-*' > $dir/Index
-               done
                for dir in $(find ./aptarchive/dists -mindepth 1 -maxdepth 1 -type d); do
                        local SUITE="$(echo "$dir" | cut -d'/' -f 4)"
                        local CODENAME="$(getcodenamefromsuite $SUITE)"
diff --git a/test/integration/skip-avoid-avoiding-breaks-predepends b/test/integration/skip-avoid-avoiding-breaks-predepends
new file mode 100755 (executable)
index 0000000..a47e8bc
--- /dev/null
@@ -0,0 +1,21 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+setupenvironment
+configarchitecture 'native'
+
+insertinstalledpackage 'looping' 'native' '1'
+insertinstalledpackage 'loop1' 'native' '1' 'Depends: loop2 (= 1)'
+insertinstalledpackage 'loop2' 'native' '1' 'Depends: loop1 (= 1)'
+
+buildsimplenativepackage 'looping' 'native' '1.15.7.2' 'stable' 'Breaks: loop2 (<= 1)'
+buildsimplenativepackage 'loop1' 'native' '2' 'stable' 'Depends: loop2 (= 2)'
+buildsimplenativepackage 'loop2' 'native' '2' 'stable' 'Depends: loop1 (= 2)
+Pre-Depends: looping (>= 1.15)'
+
+setupaptarchive
+
+aptget dist-upgrade -y -o Debug::pkgOrderList=1 #-qq 2>&1 > /dev/null
+testdpkginstalled looping loop1 loop2
diff --git a/test/integration/status-bug-64141-install-dependencies-for-on-hold b/test/integration/status-bug-64141-install-dependencies-for-on-hold
deleted file mode 100644 (file)
index c82ebd1..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-Package: apt
-Status: install ok installed
-Priority: important
-Section: admin
-Installed-Size: 6048
-Maintainer: APT Development Team <deity@lists.debian.org>
-Architecture: i386
-Version: 0.8.9
-Provides: libapt-pkg4.10
-Depends: libc6 (>= 2.3.4)
-Description: Advanced front-end for dpkg
-
-Package: libc6
-Status: install ok installed
-Priority: required
-Section: libs
-Installed-Size: 9356
-Maintainer: GNU Libc Maintainers <debian-glibc@lists.debian.org>
-Architecture: i386
-Source: eglibc
-Version: 2.3.5-7
-Provides: glibc-2.11-1
-Description: Embedded GNU C Library: Shared libraries
-
-Package: oldcrap
-Status: install ok installed
-Priority: extra
-Section: oldlibs
-Installed-Size: 1
-Maintainer: Joe Sixpack <joe@example.org>
-Architecture: all
-Version: 1-1
-Description: Old crappy nothing package
index 78c0801f2af25526b4d9e3cb8158692b0ab803b9..8c434b3ce6b70fbb4d40fa6b9074ae6db0370625 100755 (executable)
@@ -14,13 +14,13 @@ setupaptarchive
 
 # We check the Markers here as the autoremove nuker will also
 # prevent it, but to late - its better to fail earlier
-testequal 'Reading package lists...
+testequal "Reading package lists...
 Building dependency tree...
   MarkInstall coolstuff [ i386 ] < none -> 1.0 > ( other ) FU=1
     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:
   coolstuff
 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
 Inst coolstuff (1.0 unstable [all])
-Conf coolstuff (1.0 unstable [all])' aptget install coolstuff extracoolstuff- -o Debug::pkgDepCache::Marker=1 -s
+Conf coolstuff (1.0 unstable [all])" aptget install coolstuff extracoolstuff- -o Debug::pkgDepCache::Marker=1 -s
index dd9efb785c92f68f79199aaebb0cb180da783aab..530012e5ddccffb2e2082dc2d488b879b211131c 100755 (executable)
@@ -16,7 +16,7 @@ buildsimplenativepackage 'foobar' 'amd64' '1.0' 'stable' 'Depends: libc6'
 setupaptarchive
 
 aptget install libc6:i386 -t stable -y -qq 2>&1 > /dev/null
-testdpkginstalled libc6
+testdpkginstalled libc6:i386
 testequal 'Reading package lists...
 Building dependency tree...
 Reading state information...
@@ -75,8 +75,13 @@ The following packages will be upgraded:
 1 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
 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
-testdpkginstalled libc6
+# FIXME: on amd64 systems this test wouldn't run with a real upgrade
+# as APT (here i386) disagree about the native architecture, so
+# we fake it here:
+#aptget upgrade -y -qq 2>&1 > /dev/null
+aptget purge libc6 -y -qq 2>&1 >/dev/null
+aptget install libc6:i386 -y -qq 2>&1 >/dev/null
+testdpkginstalled libc6:all
 
 testequal 'Reading package lists...
 Building dependency tree...
@@ -125,7 +130,7 @@ buildsimplenativepackage 'foobar-same' 'amd64' '1.0' 'stable' 'Depends: libc6-sa
 setupaptarchive
 
 aptget install libc6-same:i386 -t stable -y -qq 2>&1 > /dev/null
-testdpkginstalled libc6-same
+testdpkginstalled libc6-same:i386
 
 testequal 'Reading package lists...
 Building dependency tree...
@@ -168,8 +173,14 @@ The following packages will be upgraded:
 1 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
 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
-testdpkginstalled libc6-same
+# FIXME: on amd64 systems this test wouldn't run with a real upgrade
+# as APT (here i386) disagree about the native architecture, so
+# we fake it here:
+#aptget upgrade -y -qq 2>&1 > /dev/null
+aptget purge libc6-same -y -qq 2>&1 >/dev/null
+aptget install libc6-same:i386 -y -qq 2>&1 >/dev/null
+testdpkginstalled libc6-same:all
+
 
 testequal "Reading package lists...
 Building dependency tree...
index 7333054cc11b47da54da8833793b413b390cc33d..fde075172f0c292e9c7b37f93ea0b1b20d1d4c19 100755 (executable)
@@ -16,30 +16,22 @@ buildsimplenativepackage 'apt' 'i386' '2' 'unstable' 'Depends: libsame (= 2)' ''
 buildsimplenativepackage 'apt2' 'amd64' '2' 'unstable' 'Depends: libsame (= 2)' '' 'required'
 
 setupaptarchive
+aptget dist-upgrade -s 2>&1 > output.apt
 
 # order in switch libsame:{amd64,i386} are unpacked is irrelevant, as both are installed - but we need to do it together
-testequalor2 'Reading package lists...
-Building dependency tree...
-The following packages will be upgraded:
-  apt:i386 apt2 libsame libsame:i386
-4 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
-Inst libsame:i386 [1] (2 unstable [i386]) [libsame:amd64 on libsame:i386] [libsame:i386 on libsame:amd64] [libsame:amd64 apt:i386 ]
-Inst libsame [1] (2 unstable [amd64]) [apt2:amd64 apt:i386 ]
-Conf libsame:i386 (2 unstable [i386]) [apt2:amd64 apt:i386 ]
-Conf libsame (2 unstable [amd64]) [apt2:amd64 apt:i386 ]
-Inst apt2 [1] (2 unstable [amd64]) [apt:i386 ]
-Conf apt2 (2 unstable [amd64]) [apt:i386 ]
-Inst apt:i386 [1] (2 unstable [i386])
-Conf apt:i386 (2 unstable [i386])' 'Reading package lists...
-Building dependency tree...
-The following packages will be upgraded:
-  apt:i386 apt2 libsame libsame:i386
-4 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
-Inst libsame [1] (2 unstable [amd64]) [libsame:amd64 on libsame:i386] [libsame:i386 on libsame:amd64] [libsame:i386 apt2:amd64 ]
-Inst libsame:i386 [1] (2 unstable [i386]) [apt2:amd64 apt:i386 ]
-Conf libsame:i386 (2 unstable [i386]) [apt2:amd64 apt:i386 ]
-Conf libsame (2 unstable [amd64]) [apt2:amd64 apt:i386 ]
-Inst apt2 [1] (2 unstable [amd64]) [apt:i386 ]
-Conf apt2 (2 unstable [amd64]) [apt:i386 ]
-Inst apt:i386 [1] (2 unstable [i386])
-Conf apt:i386 (2 unstable [i386])' aptget dist-upgrade -s
+LS_U_AMD="$(grep -o -n '^Inst libsame ' output.apt | cut -d: -f1)"
+LS_U_INT="$(grep -o -n '^Inst libsame:i386 ' output.apt | cut -d: -f1)"
+LS_C_AMD="$(grep -o -n '^Conf libsame ' output.apt | cut -d: -f1)"
+LS_C_INT="$(grep -o -n '^Conf libsame:i386 ' output.apt | cut -d: -f1)"
+
+msgtest 'Test if libsame:amd64 unpack before configure'
+test "$LS_U_AMD" -lt "$LS_C_AMD" && msgpass || msgfail
+
+msgtest 'Test if libsame:i386 unpack before configure'
+test "$LS_U_INT" -lt "$LS_C_INT" && msgpass || msgfail
+
+msgtest 'Test if libsame:amd64 unpack is before libsame:i386 configure'
+test "$LS_U_AMD" -lt "$LS_C_INT" && msgpass || msgfail
+
+msgtest 'Test if libsame:i386 unpack is before libsame:amd64 configure'
+test "$LS_U_INT" -lt "$LS_C_AMD" && msgpass || msgfail
index a1e708d2edadfdbb164444717cd5ba12302ce69e..d146b943c214b2c4026acaed3c4015e35ba88903 100755 (executable)
@@ -42,16 +42,9 @@ msgtest 'Download of nothing if none is forced' 'with Index'
 aptget update -o Acquire::Languages=none | grep -q -e 'Translation' && msgfail || msgpass
 rm -rf rootdir/var/lib/apt/lists
 
-sed -i '/i18n\/Index$/ d' $(find aptarchive -name 'Release')
+sed -i '/i18n\/Translation-.*$/ d' $(find aptarchive -name 'Release')
 signreleasefiles
 
-# we have to try as not every archive includes the i18n Index in the Release file - if it has one at all
-msgtest 'Download no Translation- if forced language is non-existent' 'with not-announced Index'
-aptget update -o Acquire::Languages=ast_DE | grep -q -e 'Translation-' && msgfail || msgpass
-rm -rf rootdir/var/lib/apt/lists
-
-find aptarchive -name 'Index' -delete
-
 msgtest 'Download of en as forced language' 'without Index'
 aptget update -o Acquire::Languages=en | grep -q -e 'Translation-en ' && msgpass || msgfail
 rm -rf rootdir/var/lib/apt/lists
index 4633ffcc3387f3d34fa87ac358eeffe3bc5b5473..e2d206fdd573adc6f6b0071a97358feddc34feb6 100755 (executable)
@@ -4,7 +4,19 @@ set -e
 TESTDIR=$(readlink -f $(dirname $0))
 . $TESTDIR/framework
 setupenvironment
-configarchitecture "i386"
+configarchitecture 'native' 'strange-arch'
+
+insertpackage 'unstable' 'unrelated' 'strange-arch' '1'
+
+insertinstalledpackage 'apt' 'native' '0.8.9' 'Depends: libc6 (>= 2.3.4)'
+insertinstalledpackage 'libc6' 'native' '2.4.1-1'
+insertinstalledpackage 'oldcrap' 'all' '1-1'
+
+insertpackage 'unstable' 'apt' 'native' '0.8.10' 'Depends: libc6 (>= 2.10), libdb4.8
+Breaks: oldcrap'
+insertpackage 'unstable' 'libc6' 'native' '2.11.2-7'
+insertpackage 'unstable' 'libdb4.8' 'native' '4.8.30-3'
+
 setupaptarchive
 
 testequal 'Reading package lists...
@@ -16,11 +28,10 @@ The following NEW packages will be installed:
 The following packages will be upgraded:
   apt libc6
 2 upgraded, 1 newly installed, 1 to remove and 0 not upgraded.
-Need to get 0 B/6724 kB of archives.
-After this operation, 1523 kB of additional disk space will be used.
+After this operation, 0 B of additional disk space will be used.
 E: Trivial Only specified but this is not a trivial operation.' aptget dist-upgrade --trivial-only
 
-echo 'apt hold' | dpkg --set-selections
+aptmark hold apt -qq
 
 testequal 'Reading package lists...
 Building dependency tree...
@@ -29,6 +40,5 @@ The following packages have been kept back:
 The following packages will be upgraded:
   libc6
 1 upgraded, 0 newly installed, 0 to remove and 1 not upgraded.
-Need to get 0 B/3881 kB of archives.
 After this operation, 0 B of additional disk space will be used.
 E: Trivial Only specified but this is not a trivial operation.' aptget dist-upgrade --trivial-only -o Test='hold-back-apt'
index 7b5724d74fbc1687e2d68b3bb62412869030c178..25f0059699b2c7458a98f81aff28142054c1a7b2 100755 (executable)
@@ -20,14 +20,15 @@ Building dependency tree...
 The following packages will be upgraded:
   openjdk-6-jre openjdk-6-jre-headless openjdk-6-jre-lib
 3 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
-  openjdk-6-jre-lib conflicts with openjdk-6-jre
-    openjdk-6-jre conflicts with openjdk-6-jre-headless
-      openjdk-6-jre-headless conflicts with openjdk-6-jre
+  openjdk-6-jre-lib:i386 conflicts with openjdk-6-jre:i386
+    openjdk-6-jre:i386 conflicts with openjdk-6-jre-headless:i386
+      openjdk-6-jre-headless:i386 conflicts with openjdk-6-jre:i386
 Remv openjdk-6-jre [6b16-1.8-0ubuntu1]
-      openjdk-6-jre-headless conflicts with openjdk-6-jre-lib
+      openjdk-6-jre-headless:i386 conflicts with openjdk-6-jre-lib:i386
 Remv openjdk-6-jre-lib [6b16-1.8-0ubuntu1]
 Inst openjdk-6-jre-headless [6b16-1.8-0ubuntu1] (6b20-1.9.8-0ubuntu1~10.04.1 unstable [i386])
-    openjdk-6-jre conflicts with openjdk-6-jre-lib
+    openjdk-6-jre:i386 conflicts with openjdk-6-jre-lib:i386
+    openjdk-6-jre:i386 conflicts with openjdk-6-jre-lib:i386
 Inst openjdk-6-jre [6b16-1.8-0ubuntu1] (6b20-1.9.8-0ubuntu1~10.04.1 unstable [i386])
 Inst openjdk-6-jre-lib [6b16-1.8-0ubuntu1] (6b20-1.9.8-0ubuntu1~10.04.1 unstable [i386])
 Conf openjdk-6-jre-lib (6b20-1.9.8-0ubuntu1~10.04.1 unstable [i386])
index c91e778442ca6c0ef5a19bee94f97d9f50c7474a..35de221155ea30b6cbff0edccf0fae9cb746490c 100755 (executable)
@@ -6,7 +6,7 @@ TESTDIR=$(readlink -f $(dirname $0))
 setupenvironment
 configarchitecture "i386"
 
-insertpackage 'unstable' 'apt' 'i386' '0.8.15'
+insertpackage 'unstable' 'rapt' 'i386' '0.8.15'
 insertpackage 'unstable' 'arch' 'i386' '1.0'
 
 setupaptarchive
@@ -22,40 +22,40 @@ testcandidate() {
        fi
 }
 
-testcandidate apt '0.8.15'
+testcandidate rapt '0.8.15'
 testequal 'N: Unable to locate package doesntexist' aptcache policy doesntexist -q=0
 testequal 'Reading package lists...
 Building dependency tree...
-0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.' aptget dist-upgrade
+0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.' aptget dist-upgrade --trivial-only
 
-echo 'Package: apt
+echo 'Package: rapt
 Pin: release a=unstable
 Pin-Priority: -1' > rootdir/etc/apt/preferences
 
-testcandidate apt '(none)'
+testcandidate rapt '(none)'
 testequal 'N: Unable to locate package doesntexist' aptcache policy doesntexist -q=0
 testequal 'Reading package lists...
 Building dependency tree...
-0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.' aptget dist-upgrade
+0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.' aptget dist-upgrade --trivial-only
 
 echo '
 Package: doesntexist
 Pin: release a=unstable
 Pin-Priority: 1000' >> rootdir/etc/apt/preferences
 
-testcandidate apt '(none)'
+testcandidate rapt '(none)'
 
 echo '
-Package: apt
+Package: rapt
 Pin: release a=unstable
 Pin-Priority: 1000' >> rootdir/etc/apt/preferences
 
-testcandidate apt '(none)'
+testcandidate rapt '(none)'
 testequal 'N: Unable to locate package doesntexist' aptcache policy doesntexist -q=0
 
 testequal 'Reading package lists...
 Building dependency tree...
-0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.' aptget dist-upgrade
+0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.' aptget dist-upgrade --trivial-only
 
 echo 'Package: arch:amd64
 Pin: release a=unstable
index 8bf02a78fbdc8e642ccf65773c666d04faf47298..4f65cfa3b384472d3142508d9bdbb6834abd69a4 100755 (executable)
@@ -153,6 +153,35 @@ runtest() {
        installaptold
 }
 
+runtest2() {
+       prepare ${PKGFILE}
+       rm -rf rootdir/var/lib/apt/lists
+       signreleasefiles 'Joe Sixpack'
+       msgtest 'Cold archive signed by' 'Joe Sixpack'
+       aptget update 2>&1 | grep -E '^(W|E): ' > /dev/null && msgfail || msgpass
+
+       # New .deb but now an unsigned archive. For example MITM to circumvent
+       # package verification.
+       prepare ${PKGFILE}-new
+       find aptarchive/ -name InRelease -delete
+       find aptarchive/ -name Release.gpg -delete
+       msgtest 'Warm archive signed by' 'nobody'
+       aptget update 2>&1 | grep -E '^(W|E): ' > /dev/null && msgfail || msgpass
+       testequal "$(cat ${PKGFILE}-new)
+" aptcache show apt
+       failaptnew
+
+       # Unsigned archive from the beginning must also be detected.
+       rm -rf rootdir/var/lib/apt/lists
+       msgtest 'Cold archive signed by' 'nobody'
+       aptget update 2>&1 | grep -E '^(W|E): ' > /dev/null && msgfail || msgpass
+       testequal "$(cat ${PKGFILE}-new)
+" aptcache show apt
+       failaptnew
+}
+runtest2
+
+
 DELETEFILE="InRelease"
 runtest
 DELETEFILE="Release.gpg"
diff --git a/test/integration/test-suggest-installed-multiarch-silbing b/test/integration/test-suggest-installed-multiarch-silbing
new file mode 100755 (executable)
index 0000000..d55d250
--- /dev/null
@@ -0,0 +1,80 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+setupenvironment
+configarchitecture 'amd64' 'i386' 'armel'
+
+insertinstalledpackage 'foo' 'i386' '1'
+insertpackage 'unstable' 'foo' 'amd64,i386' '1'
+
+insertinstalledpackage 'foo2' 'i386' '1'
+insertpackage 'unstable' 'foo2' 'i386' '1'
+
+insertinstalledpackage 'foo3' 'amd64' '1'
+insertpackage 'unstable' 'foo3' 'amd64,i386' '1'
+
+insertinstalledpackage 'samefoo' 'i386,amd64' '1' 'Multi-Arch: same'
+insertpackage 'unstable' 'samefoo' 'amd64,i386,armel' '1' 'Multi-Arch: same'
+
+insertinstalledpackage 'samefoo2' 'i386' '1' 'Multi-Arch: same'
+insertpackage 'unstable' 'samefoo2' 'amd64,i386,armel' '1' 'Multi-Arch: same'
+
+insertinstalledpackage 'mozplugger' 'i386' '1' 'Depends: iceweasel | fireweasel'
+insertinstalledpackage 'fireweasel' 'i386' '1'
+insertpackage 'unstable' 'mozplugger' 'i386,amd64' '1' 'Depends: iceweasel | fireweasel'
+
+setupaptarchive
+
+testequal "Reading package lists...
+Building dependency tree...
+Package 'foo' is not installed, so not removed. Did you mean 'foo:i386'?
+0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." aptget remove foo -s
+
+testequal "Reading package lists...
+Building dependency tree...
+The following packages will be REMOVED:
+  foo2:i386
+0 upgraded, 0 newly installed, 1 to remove and 0 not upgraded.
+Remv foo2:i386 [1]" aptget remove foo2 -s
+
+testequal "Reading package lists...
+Building dependency tree...
+The following packages will be REMOVED:
+  foo3
+0 upgraded, 0 newly installed, 1 to remove and 0 not upgraded.
+Remv foo3 [1]" aptget remove foo3 -s
+
+testequal "Reading package lists...
+Building dependency tree...
+Package 'foo3:i386' is not installed, so not removed. Did you mean 'foo3'?
+0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." aptget remove foo3:i386 -s
+
+testequalor2 "Reading package lists...
+Building dependency tree...
+Package 'samefoo:armel' is not installed, so not removed. Did you mean 'samefoo'?
+0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." "Reading package lists...
+Building dependency tree...
+Package 'samefoo:armel' is not installed, so not removed. Did you mean 'samefoo:i386'?
+0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." aptget remove samefoo:armel -s
+
+testequal "Reading package lists...
+Building dependency tree...
+Package 'samefoo2' is not installed, so not removed. Did you mean 'samefoo2:i386'?
+0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." aptget remove samefoo2 -s
+
+testequal "Reading package lists...
+Building dependency tree...
+Package 'samefoo2:armel' is not installed, so not removed. Did you mean 'samefoo2:i386'?
+0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." aptget remove samefoo2:armel -s
+
+testequal "Reading package lists...
+Building dependency tree...
+Package 'iceweasel' is not installed, so not removed
+0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." aptget remove iceweasel -s
+
+testequal "Reading package lists...
+Building dependency tree...
+Package 'fireweasel' is not installed, so not removed. Did you mean 'fireweasel:i386'?
+0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." aptget remove fireweasel:amd64 -s