]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/packagemanager.cc
Regex, --all-versions and more OR stuff
[apt.git] / apt-pkg / packagemanager.cc
index 8556687adae3653f14f548067f3db75a16228a8d..b76f78b3cf2dddb124aa4e0fc3af9bca518ee6ef 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: packagemanager.cc,v 1.15 1999/07/03 03:10:35 jgg Exp $
+// $Id: packagemanager.cc,v 1.21 1999/09/30 06:30:34 jgg Exp $
 /* ######################################################################
 
    Package Manager - Abstacts the package manager
@@ -87,31 +87,24 @@ bool pkgPackageManager::GetArchives(pkgAcquire *Owner,pkgSourceList *Sources,
 /* This is called to correct the installation when packages could not
    be downloaded. */
 bool pkgPackageManager::FixMissing()
-{
+{   
    pkgProblemResolver Resolve(Cache);
-
+   List->SetFileList(FileNames);
+   
    bool Bad = false;
    for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
    {
-      // These don't need files
-      if (Cache[I].Keep() == true)
-        continue;
-      if (Cache[I].Delete() == true)
-        continue;
-      
-      // We have a filename
-      if (FileNames[I->ID].empty() == false)
+      if (List->IsMissing(I) == false)
         continue;
-      
-      // Skip Packages that need configure only.
-      if (I.State() == pkgCache::PkgIterator::NeedsConfigure && 
-         Cache[I].Keep() == true)
-        continue;
-      
+   
       // Okay, this file is missing and we need it. Mark it for keep 
       Bad = true;
       Cache.MarkKeep(I);
    }
+   // We have to empty the list otherwise it will not have the new changes
+   delete List;
+   List = 0;
    
    if (Bad == false)
       return true;
@@ -163,7 +156,9 @@ bool pkgPackageManager::CreateOrderList()
       // Not interesting
       if ((Cache[I].Keep() == true || 
          Cache[I].InstVerIter(Cache) == I.CurrentVer()) && 
-         I.State() == pkgCache::PkgIterator::NeedsNothing)
+         I.State() == pkgCache::PkgIterator::NeedsNothing &&
+         (I.Purge() != false || Cache[I].Mode != pkgDepCache::ModeDelete ||
+          (Cache[I].iFlags & pkgDepCache::Purge) != pkgDepCache::Purge))
         continue;
       
       // Append it to the list
@@ -369,6 +364,17 @@ bool pkgPackageManager::EarlyRemove(PkgIterator Pkg)
    // Woops, it will not be re-installed!
    if (List->IsFlag(Pkg,pkgOrderList::InList) == false)
       return false;
+
+   // Essential packages get special treatment
+   if ((Pkg->Flags & pkgCache::Flag::Essential) != 0)
+   {
+      if (_config->FindB("APT::Force-LoopBreak",false) == false)
+        return _error->Error("This installation run will require temporarily "
+                             "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());
+   }
    
    bool Res = SmartRemove(Pkg);
    if (Cache[Pkg].Delete() == false)
@@ -386,7 +392,7 @@ bool pkgPackageManager::SmartRemove(PkgIterator Pkg)
       return true;
 
    List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States);
-   return Remove(Pkg);
+   return Remove(Pkg,(Cache[Pkg].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge);
 }
                                                                        /*}}}*/
 // PM::SmartUnPack - Install helper                                    /*{{{*/
@@ -408,12 +414,17 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg)
    /* See if this packages install version has any predependencies
       that are not met by 'now' packages. */
    for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList(); 
-       D.end() == false; D++)
+       D.end() == false; )
    {
-      if (D->Type == pkgCache::Dep::PreDepends)
+      // Compute a single dependency element (glob or)
+      pkgCache::DepIterator Start;
+      pkgCache::DepIterator End;
+      D.GlobOr(Start,End);
+      
+      while (End->Type == pkgCache::Dep::PreDepends)
       {
         // Look for possible ok targets.
-        Version **VList = D.AllTargets();
+        Version **VList = Start.AllTargets();
         bool Bad = true;
         for (Version **I = VList; *I != 0 && Bad == true; I++)
         {
@@ -444,18 +455,24 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg)
         }
         
         delete [] VList;
-        
-        if (Bad == true)
-           return _error->Error("Internal Error, Couldn't configure a pre-depend");
 
-        continue;
+        /* If this or element did not match then continue on to the
+           next or element until a matching element is found*/
+        if (Bad == true)
+        {          
+           if (Start == End)
+              return _error->Error("Internal Error, Couldn't configure a pre-depend");
+           Start++;
+        }
+        else
+           break;
       }
       
-      if (D->Type == pkgCache::Dep::Conflicts)
+      if (End->Type == pkgCache::Dep::Conflicts)
       {
         /* Look for conflicts. Two packages that are both in the install
            state cannot conflict so we don't check.. */
-        Version **VList = D.AllTargets();
+        Version **VList = End.AllTargets();
         for (Version **I = VList; *I != 0; I++)
         {
            VerIterator Ver(Cache,*I);
@@ -526,7 +543,7 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall()
         continue;
       }
       
-      if (Cache[Pkg].Delete() == false && FileNames[Pkg->ID].empty() == true)
+      if (List->IsMissing(Pkg) == true)
       {
         if (Debug == true)
            clog << "Sequence completed at" << Pkg.Name() << endl;