]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/depcache.cc
make all d-pointer * const pointers
[apt.git] / apt-pkg / depcache.cc
index 25c945ebb10df6db7fbab55399f22208a5314e2f..d01c142239b112cd569640d0fd0a6dd95631d459 100644 (file)
@@ -33,7 +33,6 @@
 #include <vector>
 #include <algorithm>
 #include <iostream>
-#include <sstream>
 #include <set>
 
 #include <sys/stat.h>
@@ -64,7 +63,7 @@ ConfigValueInSubTree(const char* SubTree, const char *needle)
 }
                                                                        /*}}}*/
 pkgDepCache::ActionGroup::ActionGroup(pkgDepCache &cache) :            /*{{{*/
-  cache(cache), released(false)
+  d(NULL), cache(cache), released(false)
 {
   ++cache.group_level;
 }
@@ -96,7 +95,9 @@ pkgDepCache::ActionGroup::~ActionGroup()
 // ---------------------------------------------------------------------
 /* */
 pkgDepCache::pkgDepCache(pkgCache *pCache,Policy *Plcy) :
-  group_level(0), Cache(pCache), PkgState(0), DepState(0)
+  group_level(0), Cache(pCache), PkgState(0), DepState(0),
+   iUsrSize(0), iDownloadSize(0), iInstCount(0), iDelCount(0), iKeepCount(0),
+   iBrokenCount(0), iPolicyBrokenCount(0), iBadCount(0), d(NULL)
 {
    DebugMarker = _config->FindB("Debug::pkgDepCache::Marker", false);
    DebugAutoInstall = _config->FindB("Debug::pkgDepCache::AutoInstall", false);
@@ -252,17 +253,14 @@ bool pkgDepCache::writeStateFile(OpProgress * /*prog*/, bool InstalledOnly)       /*{{
       return _error->Error(_("Failed to open StateFile %s"),
                           state.c_str());
 
-   FILE *OutFile;
-   string const outfile = state + ".tmp";
-   if((OutFile = fopen(outfile.c_str(),"w")) == NULL)
-      return _error->Error(_("Failed to write temporary StateFile %s"),
-                          outfile.c_str());
+   FileFd OutFile(state, FileFd::ReadWrite | FileFd::Atomic);
+   if (OutFile.IsOpen() == false || OutFile.Failed() == true)
+      return _error->Error(_("Failed to write temporary StateFile %s"), state.c_str());
 
    // first merge with the existing sections
    pkgTagFile tagfile(&StateFile);
    pkgTagSection section;
    std::set<string> pkgs_seen;
-   const char *nullreorderlist[] = {0};
    while(tagfile.Step(section)) {
         string const pkgname = section.FindS("Package");
         string pkgarch = section.FindS("Architecture");
@@ -271,7 +269,7 @@ bool pkgDepCache::writeStateFile(OpProgress * /*prog*/, bool InstalledOnly) /*{{
         // Silently ignore unknown packages and packages with no actual
         // version.
         pkgCache::PkgIterator pkg = Cache->FindPkg(pkgname, pkgarch);
-        if(pkg.end() || pkg.VersionList().end()) 
+        if(pkg.end() || pkg.VersionList().end())
            continue;
         StateCache const &P = PkgState[pkg->ID];
         bool newAuto = (P.Flags & Flag::Auto);
@@ -292,21 +290,17 @@ bool pkgDepCache::writeStateFile(OpProgress * /*prog*/, bool InstalledOnly)       /*{{
         if(_config->FindB("Debug::pkgAutoRemove",false))
            std::clog << "Update existing AutoInstall info: " 
                      << pkg.FullName() << std::endl;
-        TFRewriteData rewrite[3];
-        rewrite[0].Tag = "Architecture";
-        rewrite[0].Rewrite = pkg.Arch();
-        rewrite[0].NewTag = 0;
-        rewrite[1].Tag = "Auto-Installed";
-        rewrite[1].Rewrite = newAuto ? "1" : "0";
-        rewrite[1].NewTag = 0;
-        rewrite[2].Tag = 0;
-        TFRewrite(OutFile, section, nullreorderlist, rewrite);
-        fprintf(OutFile,"\n");
+
+        std::vector<pkgTagSection::Tag> rewrite;
+        rewrite.push_back(pkgTagSection::Tag::Rewrite("Architecture", pkg.Arch()));
+        rewrite.push_back(pkgTagSection::Tag::Rewrite("Auto-Installed", newAuto ? "1" : "0"));
+        section.Write(OutFile, NULL, rewrite);
+        if (OutFile.Write("\n", 1) == false)
+           return false;
         pkgs_seen.insert(pkg.FullName());
    }
-   
+
    // then write the ones we have not seen yet
-   std::ostringstream ostr;
    for(pkgCache::PkgIterator pkg=Cache->PkgBegin(); !pkg.end(); ++pkg) {
       StateCache const &P = PkgState[pkg->ID];
       if(P.Flags & Flag::Auto) {
@@ -325,19 +319,17 @@ bool pkgDepCache::writeStateFile(OpProgress * /*prog*/, bool InstalledOnly)       /*{{
            continue;
         if(debug_autoremove)
            std::clog << "Writing new AutoInstall: " << pkg.FullName() << std::endl;
-        ostr.str(string(""));
-        ostr << "Package: " << pkg.Name()
-             << "\nArchitecture: " << pkgarch
-             << "\nAuto-Installed: 1\n\n";
-        fprintf(OutFile,"%s",ostr.str().c_str());
+        std::string stanza = "Package: ";
+        stanza.append(pkg.Name())
+             .append("\nArchitecture: ").append(pkgarch)
+             .append("\nAuto-Installed: 1\n\n");
+        if (OutFile.Write(stanza.c_str(), stanza.length()) == false)
+           return false;
       }
    }
-   fclose(OutFile);
-
-   // move the outfile over the real file and set permissions
-   rename(outfile.c_str(), state.c_str());
+   if (OutFile.Close() == false)
+      return false;
    chmod(state.c_str(), 0644);
-
    return true;
 }
                                                                        /*}}}*/
@@ -957,7 +949,7 @@ bool pkgDepCache::IsModeChangeOk(ModeList const mode, PkgIterator const &Pkg,
 /* */
 struct CompareProviders {
    pkgCache::PkgIterator const Pkg;
-   CompareProviders(pkgCache::DepIterator const &Dep) : Pkg(Dep.TargetPkg()) {};
+   explicit CompareProviders(pkgCache::DepIterator const &Dep) : Pkg(Dep.TargetPkg()) {};
    //bool operator() (APT::VersionList::iterator const &AV, APT::VersionList::iterator const &BV)
    bool operator() (pkgCache::VerIterator const &AV, pkgCache::VerIterator const &BV)
    {
@@ -1315,14 +1307,18 @@ bool pkgDepCache::IsInstallOkMultiArchSameVersionSynced(PkgIterator const &Pkg,
    GrpIterator const Grp = Pkg.Group();
    for (PkgIterator P = Grp.PackageList(); P.end() == false; P = Grp.NextPkg(P))
    {
-      // not installed or version synced: fine by definition
+      // not installed or self-check: fine by definition
+      if (P->CurrentVer == 0 || P == Pkg)
+        continue;
+
+      // not having a candidate or being in sync
       // (simple string-compare as stuff like '1' == '0:1-0' can't happen here)
-      if (P->CurrentVer == 0 || strcmp(Pkg.CandVersion(), P.CandVersion()) == 0)
+      VerIterator CV = PkgState[P->ID].CandidateVerIter(*this);
+      if (CV.end() == true || strcmp(Pkg.CandVersion(), CV.VerStr()) == 0)
         continue;
+
       // packages losing M-A:same can be out-of-sync
-      VerIterator CV = PkgState[P->ID].CandidateVerIter(*this);
-      if (unlikely(CV.end() == true) ||
-           (CV->MultiArch & pkgCache::Version::Same) != pkgCache::Version::Same)
+      if ((CV->MultiArch & pkgCache::Version::Same) != pkgCache::Version::Same)
         continue;
 
       // not downloadable means the package is obsolete, so allow out-of-sync
@@ -1332,7 +1328,8 @@ bool pkgDepCache::IsInstallOkMultiArchSameVersionSynced(PkgIterator const &Pkg,
       PkgState[Pkg->ID].iFlags |= AutoKept;
       if (unlikely(DebugMarker == true))
         std::clog << OutputInDepth(Depth) << "Ignore MarkInstall of " << Pkg
-           << " as its M-A:same siblings are not version-synced" << std::endl;
+           << " as it is not in sync with its M-A:same sibling " << P
+           << " (" << Pkg.CandVersion() << " != " << CV.VerStr() << ")" << std::endl;
       return false;
    }
 
@@ -1690,13 +1687,13 @@ pkgCache::VerIterator pkgDepCache::Policy::GetCandidateVer(PkgIterator const &Pk
       
       for (VerFileIterator J = I.FileList(); J.end() == false; ++J)
       {
-        if ((J.File()->Flags & Flag::NotSource) != 0)
+        if (J.File().Flagged(Flag::NotSource))
            continue;
 
         /* Stash the highest version of a not-automatic source, we use it
            if there is nothing better */
-        if ((J.File()->Flags & Flag::NotAutomatic) != 0 ||
-            (J.File()->Flags & Flag::ButAutomaticUpgrades) != 0)
+        if (J.File().Flagged(Flag::NotAutomatic) ||
+            J.File().Flagged(Flag::ButAutomaticUpgrades))
         {
            if (Last.end() == true)
               Last = I;