CD swapping support
authorArch Librarian <arch@canonical.com>
Mon, 20 Sep 2004 16:54:10 +0000 (16:54 +0000)
committerArch Librarian <arch@canonical.com>
Mon, 20 Sep 2004 16:54:10 +0000 (16:54 +0000)
Author: jgg
Date: 1999-07-03 03:10:35 GMT
CD swapping support

13 files changed:
apt-pkg/acquire.cc
apt-pkg/acquire.h
apt-pkg/algorithms.cc
apt-pkg/deb/dpkgpm.cc
apt-pkg/deb/dpkgpm.h
apt-pkg/orderlist.cc
apt-pkg/orderlist.h
apt-pkg/packagemanager.cc
apt-pkg/packagemanager.h
cmdline/acqprogress.cc
cmdline/apt-cdrom.cc
cmdline/apt-get.cc
methods/cdrom.cc

index 734f5e7..6ea1e35 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: acquire.cc,v 1.36 1999/06/13 05:06:40 jgg Exp $
+// $Id: acquire.cc,v 1.37 1999/07/03 03:10:35 jgg Exp $
 /* ######################################################################
 
    Acquire - File Acquiration
@@ -53,15 +53,23 @@ pkgAcquire::pkgAcquire(pkgAcquireStatus *Log) : Log(Log)
 /* Free our memory, clean up the queues (destroy the workers) */
 pkgAcquire::~pkgAcquire()
 {
-   while (Items.size() != 0)
-      delete Items[0];
-
    while (Configs != 0)
    {
       MethodConfig *Jnk = Configs;
       Configs = Configs->Next;
       delete Jnk;
    }   
+   
+   Shutdown();
+}
+                                                                       /*}}}*/
+// pkgAcquire::Shutdown - Clean out the acquire object                 /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void pkgAcquire::Shutdown()
+{
+   while (Items.size() != 0)
+      delete Items[0];
 
    while (Queues != 0)
    {
@@ -125,7 +133,7 @@ void pkgAcquire::Remove(Worker *Work)
 // Acquire::Enqueue - Queue an URI for fetching                                /*{{{*/
 // ---------------------------------------------------------------------
 /* This is the entry point for an item. An item calls this function when
-   it is construction which creates a queue (based on the current queue
+   it is constructed which creates a queue (based on the current queue
    mode) and puts the item in that queue. If the system is running then
    the queue might be started. */
 void pkgAcquire::Enqueue(ItemDesc &Item)
index 6a1583c..4477615 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: acquire.h,v 1.21 1999/06/13 05:06:40 jgg Exp $
+// $Id: acquire.h,v 1.22 1999/07/03 03:10:35 jgg Exp $
 /* ######################################################################
 
    Acquire - File Acquiration
@@ -82,8 +82,8 @@ class pkgAcquire
    string QueueName(string URI,MethodConfig const *&Config);
 
    // FDSET managers for derived classes
-   void SetFds(int &Fd,fd_set *RSet,fd_set *WSet);
-   void RunFds(fd_set *RSet,fd_set *WSet);   
+   virtual void SetFds(int &Fd,fd_set *RSet,fd_set *WSet);
+   virtual void RunFds(fd_set *RSet,fd_set *WSet);   
 
    // A queue calls this when it dequeues an item
    void Bump();
@@ -95,7 +95,8 @@ class pkgAcquire
    enum RunResult {Continue,Failed,Cancelled};
 
    RunResult Run();
-
+   void Shutdown();
+   
    // Simple iteration mechanism
    inline Worker *WorkersBegin() {return Workers;};
    Worker *WorkerStep(Worker *I);
index 60da32d..21db989 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: algorithms.cc,v 1.19 1999/06/28 03:11:24 jgg Exp $
+// $Id: algorithms.cc,v 1.20 1999/07/03 03:10:35 jgg Exp $
 /* ######################################################################
 
    Algorithms - A set of misc algorithms
@@ -33,6 +33,11 @@ pkgSimulate::pkgSimulate(pkgDepCache &Cache) : pkgPackageManager(Cache),
 {
    Flags = new unsigned char[Cache.HeaderP->PackageCount];
    memset(Flags,0,sizeof(*Flags)*Cache.HeaderP->PackageCount);
+
+   // Fake a filename so as not to activate the media swapping
+   string Jnk = "SIMULATE";
+   for (int I = 0; I != Cache.Head().PackageCount; I++)
+      FileNames[I] = Jnk;
 }
                                                                        /*}}}*/
 // Simulate::Install - Simulate unpacking of a package                 /*{{{*/
index 478b119..998750b 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: dpkgpm.cc,v 1.9 1999/04/20 05:02:09 jgg Exp $
+// $Id: dpkgpm.cc,v 1.10 1999/07/03 03:10:35 jgg Exp $
 /* ######################################################################
 
    DPKG Package Manager - Provide an interface to dpkg
@@ -299,3 +299,11 @@ bool pkgDPkgPM::Go()
    return true;
 }
                                                                        /*}}}*/
+// pkgDpkgPM::Reset - Dump the contents of the command list            /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void pkgDPkgPM::Reset() 
+{
+   List.erase(List.begin(),List.end());
+}
+                                                                       /*}}}*/
index db6ce2a..d7898da 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: dpkgpm.h,v 1.3 1999/01/31 08:49:39 jgg Exp $
+// $Id: dpkgpm.h,v 1.4 1999/07/03 03:10:35 jgg Exp $
 /* ######################################################################
 
    DPKG Package Manager - Provide an interface to dpkg
@@ -41,6 +41,7 @@ class pkgDPkgPM : public pkgPackageManager
    virtual bool Configure(PkgIterator Pkg);
    virtual bool Remove(PkgIterator Pkg);
    virtual bool Go();
+   virtual void Reset();
    
    public:
 
index 04d8c4c..c831e9a 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: orderlist.cc,v 1.3 1998/09/26 05:34:21 jgg Exp $
+// $Id: orderlist.cc,v 1.4 1999/07/03 03:10:35 jgg Exp $
 /* ######################################################################
 
    Order List - Represents and Manipulates an ordered list of packages.
@@ -42,7 +42,7 @@
    arbitary priority to give quite abit of control over the final unpacking
    order.
 
-   The rules listed above my never be violated and are called Critical.
+   The rules listed above may never be violated and are called Critical.
    When a critical rule is violated then a loop condition is recorded
    and will have to be delt with in the caller.
    
@@ -65,6 +65,7 @@ pkgOrderList *pkgOrderList::Me = 0;
 /* */
 pkgOrderList::pkgOrderList(pkgDepCache &Cache) : Cache(Cache)
 {
+   FileList = 0;
    Primary = 0;
    Secondary = 0;
    RevDepends = 0;
@@ -93,7 +94,7 @@ pkgOrderList::~pkgOrderList()
 // ---------------------------------------------------------------------
 /* The caller is expeted to have setup the desired probe state */
 bool pkgOrderList::DoRun()
-{
+{   
    // Temp list
    unsigned long Size = Cache.HeaderP->PackageCount;
    Package **NList = new Package *[Size];
@@ -128,6 +129,8 @@ bool pkgOrderList::DoRun()
    fatal and indicate that the packages cannot be installed. */
 bool pkgOrderList::OrderCritical()
 {
+   FileList = 0;
+   
    Primary = &DepUnPackPre;
    Secondary = 0;
    RevDepends = 0;
@@ -150,8 +153,10 @@ bool pkgOrderList::OrderCritical()
 // ---------------------------------------------------------------------
 /* This performs complete unpacking ordering and creates an order that is
    suitable for unpacking */
-bool pkgOrderList::OrderUnpack()
+bool pkgOrderList::OrderUnpack(string *FileList)
 {
+   this->FileList = FileList;
+
    Primary = &DepUnPackCrit;
    Secondary = &DepConfigure;
    RevDepends = &DepUnPackDep;
@@ -161,7 +166,7 @@ bool pkgOrderList::OrderUnpack()
    // Sort
    Me = this;
    qsort(List,End - List,sizeof(*List),&OrderCompareA);
-   
+
    if (DoRun() == false)
       return false;
    
@@ -197,6 +202,7 @@ bool pkgOrderList::OrderUnpack()
    for configuration */
 bool pkgOrderList::OrderConfigure()
 {
+   FileList = 0;
    Primary = &DepConfigure;
    Secondary = 0;
    RevDepends = 0;
@@ -214,7 +220,11 @@ int pkgOrderList::Score(PkgIterator Pkg)
    // Removal is always done first
    if (Cache[Pkg].Delete() == true)
       return 200;
-
+   
+   // This should never happen..
+   if (Cache[Pkg].InstVerIter(Cache).end() == true)
+      return -1;
+   
    int Score = 0;
    if ((Pkg->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
       Score += 100;
@@ -248,7 +258,7 @@ int pkgOrderList::FileCmp(PkgIterator A,PkgIterator B)
    
    if (Cache[A].InstVerIter(Cache).FileList().end() == true)
       return -1;
-   if (Cache[A].InstVerIter(Cache).FileList().end() == true)
+   if (Cache[B].InstVerIter(Cache).FileList().end() == true)
       return 1;
    
    pkgCache::PackageFile *FA = Cache[A].InstVerIter(Cache).FileList().File();
@@ -260,6 +270,18 @@ int pkgOrderList::FileCmp(PkgIterator A,PkgIterator B)
    return 0;
 }
                                                                        /*}}}*/
+// BoolCompare - Comparison function for two booleans                  /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+static int BoolCompare(bool A,bool B)
+{
+   if (A == B)
+      return 0;
+   if (A == false)
+      return -1;
+   return 1;
+}
+                                                                       /*}}}*/
 // OrderList::OrderCompareA - Order the installation by op             /*{{{*/
 // ---------------------------------------------------------------------
 /* This provides a first-pass sort of the list and gives a decent starting
@@ -269,6 +291,19 @@ int pkgOrderList::OrderCompareA(const void *a, const void *b)
    PkgIterator A(Me->Cache,*(Package **)a);
    PkgIterator B(Me->Cache,*(Package **)b);
 
+   // We order packages with a set state toward the front
+   int Res;
+   if ((Res = BoolCompare(Me->IsNow(A),Me->IsNow(B))) == 0)
+      return -1*Res;
+   
+   // We order missing files to toward the end
+   if (Me->FileList != 0)
+   {
+      if ((Res = BoolCompare(Me->FileList[A->ID].empty() && !Me->Cache[A].Delete(),
+                            Me->FileList[B->ID].empty() && !Me->Cache[B].Delete())) == 0)
+        return -1*Res;
+   }
+   
    if (A.State() != pkgCache::PkgIterator::NeedsNothing && 
        B.State() == pkgCache::PkgIterator::NeedsNothing)
       return -1;
@@ -419,34 +454,37 @@ bool pkgOrderList::VisitNode(PkgIterator Pkg)
    // Perform immedate configuration of the package if so flagged.
    if (IsFlag(Pkg,Immediate) == true && Primary != &DepUnPackPre)
       Primary = &DepUnPackPreD;
-      
-   bool Res = true;
-   if (Cache[Pkg].Delete() == false)
+
+   if (IsNow(Pkg) == true)
    {
-      // Primary
-      Res &= Res && VisitDeps(Primary,Pkg);
-      Res &= Res && VisitRDeps(Primary,Pkg);
-      Res &= Res && VisitRProvides(Primary,Pkg.CurrentVer());
-      Res &= Res && VisitRProvides(Primary,Cache[Pkg].InstVerIter(Cache));
-      
-      // RevDep
-      Res &= Res && VisitRDeps(RevDepends,Pkg);
-      Res &= Res && VisitRProvides(RevDepends,Pkg.CurrentVer());
-      Res &= Res && VisitRProvides(RevDepends,Cache[Pkg].InstVerIter(Cache));
-       
-      // Secondary
-      Res &= Res && VisitDeps(Secondary,Pkg);
-      Res &= Res && VisitRDeps(Secondary,Pkg);
-      Res &= Res && VisitRProvides(Secondary,Pkg.CurrentVer());
-      Res &= Res && VisitRProvides(Secondary,Cache[Pkg].InstVerIter(Cache));
-   }
-   else
-   { 
-      // RevDep
-      Res &= Res && VisitRDeps(Remove,Pkg);
-      Res &= Res && VisitRProvides(Remove,Pkg.CurrentVer());
+      bool Res = true;
+      if (Cache[Pkg].Delete() == false)
+      {
+        // Primary
+        Res &= Res && VisitDeps(Primary,Pkg);
+        Res &= Res && VisitRDeps(Primary,Pkg);
+        Res &= Res && VisitRProvides(Primary,Pkg.CurrentVer());
+        Res &= Res && VisitRProvides(Primary,Cache[Pkg].InstVerIter(Cache));
+        
+        // RevDep
+        Res &= Res && VisitRDeps(RevDepends,Pkg);
+        Res &= Res && VisitRProvides(RevDepends,Pkg.CurrentVer());
+        Res &= Res && VisitRProvides(RevDepends,Cache[Pkg].InstVerIter(Cache));
+        
+        // Secondary
+        Res &= Res && VisitDeps(Secondary,Pkg);
+        Res &= Res && VisitRDeps(Secondary,Pkg);
+        Res &= Res && VisitRProvides(Secondary,Pkg.CurrentVer());
+        Res &= Res && VisitRProvides(Secondary,Cache[Pkg].InstVerIter(Cache));
+      }
+      else
+      { 
+        // RevDep
+        Res &= Res && VisitRDeps(Remove,Pkg);
+        Res &= Res && VisitRProvides(Remove,Pkg.CurrentVer());
+      }
    }
-
+   
    if (IsFlag(Pkg,Added) == false)
    {
       Flag(Pkg,Added,Added | AddPending);
index 2065fc4..7a33b97 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: orderlist.h,v 1.2 1998/07/12 23:58:29 jgg Exp $
+// $Id: orderlist.h,v 1.3 1999/07/03 03:10:35 jgg Exp $
 /* ######################################################################
 
    Order List - Represents and Manipulates an ordered list of packages.
@@ -48,6 +48,7 @@ class pkgOrderList
    // State
    Package **End;
    Package **List;
+   string *FileList;
    DepIterator Loops[20];
    int LoopCount;
    int Depth;
@@ -111,7 +112,7 @@ class pkgOrderList
    
    // Ordering modes
    bool OrderCritical();
-   bool OrderUnpack();
+   bool OrderUnpack(string *FileList = 0);
    bool OrderConfigure();
 
    int Score(PkgIterator Pkg);
index 3b09871..8556687 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: packagemanager.cc,v 1.14 1999/02/21 08:38:53 jgg Exp $
+// $Id: packagemanager.cc,v 1.15 1999/07/03 03:10:35 jgg Exp $
 /* ######################################################################
 
    Package Manager - Abstacts the package manager
@@ -60,7 +60,8 @@ bool pkgPackageManager::GetArchives(pkgAcquire *Owner,pkgSourceList *Sources,
    for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++)
    {
       PkgIterator Pkg(Cache,*I);
-
+      FileNames[Pkg->ID] = string();
+      
       // Skip packages to erase
       if (Cache[Pkg].Delete() == true)
         continue;
@@ -69,7 +70,11 @@ bool pkgPackageManager::GetArchives(pkgAcquire *Owner,pkgSourceList *Sources,
       if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure && 
          Cache[Pkg].Keep() == true)
         continue;
-      
+
+      // Skip already processed packages
+      if (List->IsNow(Pkg) == false)
+        continue;
+        
       new pkgAcqArchive(Owner,Sources,Recs,Cache[Pkg].InstVerIter(Cache),
                        FileNames[Pkg->ID]);
    }
@@ -122,6 +127,9 @@ bool pkgPackageManager::FixMissing()
    going to change. */
 bool pkgPackageManager::CreateOrderList()
 {
+   if (List != 0)
+      return true;
+   
    delete List;
    List = new pkgOrderList(Cache);
    
@@ -487,58 +495,96 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg)
 // PM::OrderInstall - Installation ordering routine                    /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-bool pkgPackageManager::OrderInstall()
+pkgPackageManager::OrderResult pkgPackageManager::OrderInstall()
 {
    if (CreateOrderList() == false)
-      return false;
+      return Failed;
+
+   Reset();
    
    if (Debug == true)
       clog << "Begining to order" << endl;
-   
-   if (List->OrderUnpack() == false)
-      return _error->Error("Internal ordering error");
 
+   if (List->OrderUnpack(FileNames) == false)
+   {
+      _error->Error("Internal ordering error");
+      return Failed;
+   }
+   
    if (Debug == true)
       clog << "Done ordering" << endl;
 
+   bool DoneSomething = false;
    for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++)
    {
       PkgIterator Pkg(Cache,*I);
+
+      if (List->IsNow(Pkg) == false)
+      {
+        if (Debug == true)
+           clog << "Skipping already done " << Pkg.Name() << endl;
+        continue;
+      }
+      
+      if (Cache[Pkg].Delete() == false && FileNames[Pkg->ID].empty() == true)
+      {
+        if (Debug == true)
+           clog << "Sequence completed at" << Pkg.Name() << endl;
+        if (DoneSomething == false)
+        {
+           _error->Error("Internal Error, ordering was unable to handle the media swap");
+           return Failed;
+        }       
+        return Incomplete;
+      }
       
       // Sanity check
       if (Cache[Pkg].Keep() == true && Pkg.State() == pkgCache::PkgIterator::NeedsNothing)
-        return _error->Error("Internal Error, trying to manipulate a kept package");
+      {
+        _error->Error("Internal Error, trying to manipulate a kept package");
+        return Failed;
+      }
       
       // Perform a delete or an install
       if (Cache[Pkg].Delete() == true)
       {
         if (SmartRemove(Pkg) == false)
-           return false;        
+           return Failed;
       }
       else
         if (SmartUnPack(Pkg) == false)
-           return false;
+           return Failed;
+      DoneSomething = true;
    }
    
    // Final run through the configure phase
    if (ConfigureAll() == false)
-      return false;
+      return Failed;
 
    // Sanity check
    for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++)
+   {
       if (List->IsFlag(*I,pkgOrderList::Configured) == false)
-        return _error->Error("Internal error, packages left unconfigured. %s",
-                             PkgIterator(Cache,*I).Name());
-
-   return true;
+      {
+        _error->Error("Internal error, packages left unconfigured. %s",
+                      PkgIterator(Cache,*I).Name());
+        return Failed;
+      }
+   }   
+        
+   return Completed;
 }
                                                                        /*}}}*/
 // PM::DoInstall - Does the installation                               /*{{{*/
 // ---------------------------------------------------------------------
 /* This uses the filenames in FileNames and the information in the
    DepCache to perform the installation of packages.*/
-bool pkgPackageManager::DoInstall()
+pkgPackageManager::OrderResult pkgPackageManager::DoInstall()
 {
-   return OrderInstall() && Go();
+   OrderResult Res = OrderInstall();
+   if (Res != Failed)
+      if (Go() == false)
+        return Failed;
+   return Res;
 }
                                                                        /*}}}*/
index 5265c31..6dbf94d 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: packagemanager.h,v 1.7 1998/11/22 23:37:06 jgg Exp $
+// $Id: packagemanager.h,v 1.8 1999/07/03 03:10:35 jgg Exp $
 /* ######################################################################
 
    Package Manager - Abstacts the package manager
@@ -38,6 +38,10 @@ class pkgOrderList;
 class pkgRecords;
 class pkgPackageManager
 {
+   public:
+   
+   enum OrderResult {Completed,Failed,Incomplete};
+   
    protected:
    string *FileNames;
    pkgDepCache &Cache;
@@ -53,7 +57,7 @@ class pkgPackageManager
    typedef pkgCache::Package Package;
       
    bool DepAdd(pkgOrderList &Order,PkgIterator P,int Depth = 0);
-   bool OrderInstall();
+   OrderResult OrderInstall();
    bool CheckRConflicts(PkgIterator Pkg,DepIterator Dep,const char *Ver);
    bool CreateOrderList();
    
@@ -72,13 +76,14 @@ class pkgPackageManager
    virtual bool Configure(PkgIterator /*Pkg*/) {return false;};
    virtual bool Remove(PkgIterator /*Pkg*/) {return false;};
    virtual bool Go() {return true;};
+   virtual void Reset() {};
    
    public:
-
+      
    // Main action members
    bool GetArchives(pkgAcquire *Owner,pkgSourceList *Sources,
                    pkgRecords *Recs);
-   bool DoInstall();
+   OrderResult DoInstall();
    bool FixMissing();
    
    pkgPackageManager(pkgDepCache &Cache);
index d6031ad..f16843c 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: acqprogress.cc,v 1.15 1999/06/13 05:06:40 jgg Exp $
+// $Id: acqprogress.cc,v 1.16 1999/07/03 03:10:35 jgg Exp $
 /* ######################################################################
 
    Acquire Progress - Command line progress meter 
@@ -92,6 +92,9 @@ void AcqTextStatus::Fail(pkgAcquire::ItemDesc &Itm)
    if (Quiet > 1)
       return;
 
+   if (Itm.Owner->Status == pkgAcquire::Item::StatIdle)
+      return;
+      
    if (Quiet <= 0)
       cout << '\r' << BlankLine << '\r';
    
index dd45e9b..67c3bc7 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: apt-cdrom.cc,v 1.25 1999/05/29 21:49:58 jgg Exp $
+// $Id: apt-cdrom.cc,v 1.26 1999/07/03 03:10:35 jgg Exp $
 /* ######################################################################
    
    APT CDROM - Tool for handling APT's CDROM database.
@@ -988,7 +988,8 @@ bool DoAdd(CommandLine &)
       cout << "deb \"cdrom:" << Name << "/" << string(*I,0,Space) << 
         "\" " << string(*I,Space+1) << endl;
    }
-      
+
+   cout << "Repeat this process for the rest of the CDs in your set." << endl;
    return true;
 }
                                                                        /*}}}*/
index ca93dcd..f81d22d 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: apt-get.cc,v 1.66 1999/06/24 04:06:31 jgg Exp $
+// $Id: apt-get.cc,v 1.67 1999/07/03 03:10:36 jgg Exp $
 /* ######################################################################
    
    apt-get - Cover for dpkg
@@ -470,7 +470,12 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,bool Saftey =
    if (_config->FindB("APT::Get::Simulate") == true)
    {
       pkgSimulate PM(Cache);
-      return PM.DoInstall();
+      pkgPackageManager::OrderResult Res = PM.DoInstall();
+      if (Res == pkgPackageManager::Failed)
+        return false;
+      if (Res != pkgPackageManager::Completed)
+        return _error->Error("Internal Error, Ordering didn't finish");
+      return true;
    }
    
    // Create the text record parser
@@ -589,60 +594,75 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,bool Saftey =
    }
    
    // Run it
-   if (_config->FindB("APT::Get::No-Download",false) == false)
-      if( Fetcher.Run() == pkgAcquire::Failed)
-        return false;
-
-   // Print out errors
-   bool Failed = false;
-   bool Transient = false;
-   for (pkgAcquire::Item **I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
+   while (1)
    {
-      if ((*I)->Status == pkgAcquire::Item::StatDone &&
-         (*I)->Complete == true)
-        continue;
+      if (_config->FindB("APT::Get::No-Download",false) == false)
+        if( Fetcher.Run() == pkgAcquire::Failed)
+           return false;
       
-      (*I)->Finished();
-      
-      if ((*I)->Status == pkgAcquire::Item::StatIdle)
+      // Print out errors
+      bool Failed = false;
+      bool Transient = false;
+      for (pkgAcquire::Item **I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
       {
-        Transient = true;
+        if ((*I)->Status == pkgAcquire::Item::StatDone &&
+            (*I)->Complete == true)
+           continue;
+        
+        (*I)->Finished();
+        
+        if ((*I)->Status == pkgAcquire::Item::StatIdle)
+        {
+           Transient = true;
+           // Failed = true;
+           continue;
+        }
+        
+        cerr << "Failed to fetch " << (*I)->DescURI() << endl;
+        cerr << "  " << (*I)->ErrorText << endl;
         Failed = true;
-        continue;
       }
       
-      cerr << "Failed to fetch " << (*I)->DescURI() << endl;
-      cerr << "  " << (*I)->ErrorText << endl;
-      Failed = true;
-   }
-
-   if (_config->FindB("APT::Get::Download-Only",false) == true)
-   {
+      if (_config->FindB("APT::Get::Download-Only",false) == true)
+      {
+        if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
+           return _error->Error("Some files failed to download");
+        return true;
+      }
+      
       if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
-        return _error->Error("Some files failed to download");
-      return true;
-   }
-   
-   if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
-   {
-      if (Transient == true)
       {
-        c2out << "Upgrading with disk swapping is not supported in this version." << endl;
-        c2out << "Try running multiple times with --fix-missing" << endl;
+        /*if (Transient == true)
+        {
+           c2out << "Upgrading with disk swapping is not supported in this version." << endl;
+           c2out << "Try running multiple times with --fix-missing" << endl;
+        }*/
+        
+        return _error->Error("Unable to fetch some archives, maybe try with --fix-missing?");
       }
       
-      return _error->Error("Unable to fetch some archives, maybe try with --fix-missing?");
-   }
-   
-   // Try to deal with missing package files
-   if (PM.FixMissing() == false)
-   {
-      cerr << "Unable to correct missing packages." << endl;
-      return _error->Error("Aborting Install.");
-   }
-   
-   Cache.ReleaseLock();
-   return PM.DoInstall();
+      if (Transient == true && Failed == true)
+        return _error->Error("--fix-missing and media swapping is not currently supported");
+      
+      // Try to deal with missing package files
+      if (Failed == true && PM.FixMissing() == false)
+      {
+        cerr << "Unable to correct missing packages." << endl;
+        return _error->Error("Aborting Install.");
+      }
+      
+      Cache.ReleaseLock();
+      pkgPackageManager::OrderResult Res = PM.DoInstall();
+      if (Res == pkgPackageManager::Failed || _error->PendingError() == true)
+        return false;
+      if (Res == pkgPackageManager::Completed)
+        return true;
+      
+      // Reload the fetcher object and loop again for media swapping
+      Fetcher.Shutdown();
+      if (PM.GetArchives(&Fetcher,&List,&Recs) == false)
+        return false;
+   }   
 }
                                                                        /*}}}*/
 
index c702e2d..e46fc97 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: cdrom.cc,v 1.11 1999/06/09 23:06:39 jgg Exp $
+// $Id: cdrom.cc,v 1.12 1999/07/03 03:10:36 jgg Exp $
 /* ######################################################################
 
    CDROM URI method for APT
@@ -114,7 +114,7 @@ bool CDROMMethod::Fetch(FetchItem *Itm)
    if (CDROM[0] == '.')
       CDROM= SafeGetCWD() + '/' + CDROM;
    string NewID;
-   while (1)
+   while (CurrentID.empty() == true)
    {
       bool Hit = false;
       for (unsigned int Version = 2; Version != 0; Version--)
@@ -142,6 +142,7 @@ bool CDROMMethod::Fetch(FetchItem *Itm)
                              CDROM.c_str());
       if (MediaFail(Get.Host,CDROM) == false)
       {
+        clog << "M-Fail" << endl;
         CurrentID = "FAIL";
         Fail("Wrong CD",true);
         return true;
@@ -156,7 +157,8 @@ bool CDROMMethod::Fetch(FetchItem *Itm)
    if (stat(Res.Filename.c_str(),&Buf) != 0)
       return _error->Error("File not found");
    
-   CurrentID = NewID;
+   if (NewID.empty() == false)
+      CurrentID = NewID;
    Res.LastModified = Buf.st_mtime;
    Res.IMSHit = true;
    Res.Size = Buf.st_size;