#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>
/*}}}*/
}
}
/*}}}*/
+// 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
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());
// 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++;
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;
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;
I->CurrentItem->Owner->Complete == false)
TotalBytes += I->CurrentSize;
}
+ }
// Normalize the figures and account for unknown size downloads
if (TotalBytes <= 0)
// 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;
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)
{
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());