]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/acquire.cc
Rework TransactionID stuff
[apt.git] / apt-pkg / acquire.cc
index a187a00ae9752fc900a2797302cf369780465816..33afd8f1f8ffc37aee1b760ece99f07317bfe22a 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <iomanip>
 
 #include <dirent.h>
 #include <sys/time.h>
 #include <sys/select.h>
 #include <errno.h>
+#include <sys/stat.h>
 
 #include <apti18n.h>
                                                                        /*}}}*/
@@ -167,6 +169,74 @@ void pkgAcquire::Remove(Item *Itm)
    }
 }
                                                                        /*}}}*/
+// Acquire::AbortTransaction - Remove a transaction                    /*{{{*/
+void pkgAcquire::AbortTransaction(unsigned long TransactionID)
+{
+   if(_config->FindB("Debug::Acquire::Transaction", false) == true)
+      std::clog << "AbortTransaction: " << TransactionID << std::endl;
+
+   std::vector<Item*> Transaction;
+   for (ItemIterator I = Items.begin(); I != Items.end(); ++I)
+      if((*I)->TransactionID == TransactionID)
+         Transaction.push_back(*I);
+   
+   for (std::vector<Item*>::iterator I = Transaction.begin();
+        I != Transaction.end(); ++I)
+   {
+      if(_config->FindB("Debug::Acquire::Transaction", false) == true)
+         std::clog << "  Cancel: " << (*I)->DestFile << std::endl;
+      //Dequeue(*I);
+      (*I)->Status = pkgAcquire::Item::StatError;
+   }
+}
+                                                                       /*}}}*/
+bool pkgAcquire::TransactionHasError(unsigned long TransactionID)
+{
+   std::vector<Item*> Transaction;
+   for (ItemIterator I = Items.begin(); I != Items.end(); ++I)
+      if((*I)->TransactionID == TransactionID)
+         if((*I)->Status == pkgAcquire::Item::StatError ||
+            (*I)->Status == pkgAcquire::Item::StatAuthError)
+            return true;
+
+   return false;
+}
+// Acquire::CommitTransaction - Commit a transaction                   /*{{{*/
+void pkgAcquire::CommitTransaction(unsigned long TransactionID)
+{
+   if(_config->FindB("Debug::Acquire::Transaction", false) == true)
+      std::clog << "CommitTransaction: " << TransactionID << std::endl;
+
+   std::vector<Item*> Transaction;
+   for (ItemIterator I = Items.begin(); I != Items.end(); ++I)
+      if((*I)->TransactionID == TransactionID)
+         Transaction.push_back(*I);
+   
+   // move new files into place *and* remove files that are not
+   // part of the transaction but are still on disk
+   for (std::vector<Item*>::iterator I = Transaction.begin();
+        I != Transaction.end(); ++I)
+   {
+      if((*I)->PartialFile != "")
+      {
+         if(_config->FindB("Debug::Acquire::Transaction", false) == true)
+            std::clog << "mv " 
+                      << (*I)->PartialFile << " -> " 
+                      <<  (*I)->DestFile << std::endl;
+         Rename((*I)->PartialFile, (*I)->DestFile);
+         chmod((*I)->DestFile.c_str(),0644);
+      } else {
+         if(_config->FindB("Debug::Acquire::Transaction", false) == true)
+            std::clog << "rm " 
+                      <<  (*I)->DestFile << std::endl;
+         unlink((*I)->DestFile.c_str());
+      }
+      // mark that this transaction is finished
+      (*I)->TransactionID = 0;
+   }
+}
+                                                                       /*}}}*/
+
 // Acquire::Add - Add a worker                                         /*{{{*/
 // ---------------------------------------------------------------------
 /* A list of workers is kept so that the select loop can direct their FD
@@ -486,6 +556,9 @@ bool pkgAcquire::Clean(string Dir)
    if (DirectoryExists(Dir) == false)
       return true;
 
+   if(Dir == "/")
+      return _error->Error(_("Clean of %s is not supported"), Dir.c_str());
+
    DIR *D = opendir(Dir.c_str());   
    if (D == 0)
       return _error->Errno("opendir",_("Unable to read %s"),Dir.c_str());
@@ -821,7 +894,9 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner)
    // Compute the total number of bytes to fetch
    unsigned int Unknown = 0;
    unsigned int Count = 0;
-   for (pkgAcquire::ItemCIterator I = Owner->ItemsBegin(); I != Owner->ItemsEnd();
+   bool UnfetchedReleaseFiles = false;
+   for (pkgAcquire::ItemCIterator I = Owner->ItemsBegin(); 
+        I != Owner->ItemsEnd();
        ++I, ++Count)
    {
       TotalItems++;
@@ -832,6 +907,13 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner)
       if ((*I)->Local == true)
         continue;
 
+      // see if the method tells us to expect more
+      TotalItems += (*I)->ExpectedAdditionalItems;
+
+      // check if there are unfetched Release files
+      if ((*I)->Complete == false && (*I)->ExpectedAdditionalItems > 0)
+         UnfetchedReleaseFiles = true;
+
       TotalBytes += (*I)->FileSize;
       if ((*I)->Complete == true)
         CurrentBytes += (*I)->FileSize;
@@ -843,6 +925,7 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner)
    unsigned long long ResumeSize = 0;
    for (pkgAcquire::Worker *I = Owner->WorkersBegin(); I != 0;
        I = Owner->WorkerStep(I))
+   {
       if (I->CurrentItem != 0 && I->CurrentItem->Owner->Complete == false)
       {
         CurrentBytes += I->CurrentSize;
@@ -853,6 +936,7 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner)
             I->CurrentItem->Owner->Complete == false)
            TotalBytes += I->CurrentSize;
       }
+   }
    
    // Normalize the figures and account for unknown size downloads
    if (TotalBytes <= 0)
@@ -863,6 +947,12 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner)
    // Wha?! Is not supposed to happen.
    if (CurrentBytes > TotalBytes)
       CurrentBytes = TotalBytes;
+
+   // debug
+   if (_config->FindB("Debug::acquire::progress", false) == true)
+      std::clog << " Bytes: " 
+                << SizeToStr(CurrentBytes) << " / " << SizeToStr(TotalBytes) 
+                << std::endl;
    
    // Compute the CPS
    struct timeval NewTime;
@@ -883,6 +973,14 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner)
       Time = NewTime;
    }
 
+   // calculate the percentage, if we have too little data assume 1%
+   if (TotalBytes > 0 && UnfetchedReleaseFiles)
+      Percent = 0;
+   else 
+      // use both files and bytes because bytes can be unreliable
+      Percent = (0.8 * (CurrentBytes/float(TotalBytes)*100.0) + 
+                 0.2 * (CurrentItems/float(TotalItems)*100.0));
+
    int fd = _config->FindI("APT::Status-Fd",-1);
    if(fd > 0) 
    {
@@ -900,13 +998,11 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner)
       else
         snprintf(msg,sizeof(msg), _("Retrieving file %li of %li"), i, TotalItems);
         
-
-
       // build the status str
       status << "dlstatus:" << i
-            << ":"  << (CurrentBytes/float(TotalBytes)*100.0) 
-            << ":" << msg 
-            << endl;
+             << ":"  << std::setprecision(3) << Percent
+             << ":" << msg 
+             << endl;
 
       std::string const dlstatus = status.str();
       FileFd::Write(fd, dlstatus.c_str(), dlstatus.size());