X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/1e3f4083db29bba600b9725e9456b0e140975c99..60323ed7fde01e8c013616e2d428bf9718f2fbc7:/apt-pkg/acquire.cc?ds=inline diff --git a/apt-pkg/acquire.cc b/apt-pkg/acquire.cc index 120e809e1..be4e494e0 100644 --- a/apt-pkg/acquire.cc +++ b/apt-pkg/acquire.cc @@ -23,13 +23,21 @@ #include #include +#include +#include #include #include #include +#include +#include +#include +#include #include #include +#include #include +#include #include /*}}}*/ @@ -161,6 +169,75 @@ 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 Transaction; + for (ItemIterator I = Items.begin(); I != Items.end(); ++I) + if((*I)->TransactionID == TransactionID) + Transaction.push_back(*I); + + for (std::vector::iterator I = Transaction.begin(); + I != Transaction.end(); ++I) + { + if(_config->FindB("Debug::Acquire::Transaction", false) == true) + std::clog << " Cancel: " << (*I)->DestFile << std::endl; + // the transaction will abort, so stop anything that is idle + if ((*I)->Status == pkgAcquire::Item::StatIdle) + (*I)->Status = pkgAcquire::Item::StatDone; + } +} + /*}}}*/ +bool pkgAcquire::TransactionHasError(unsigned long TransactionID) +{ + std::vector Transaction; + for (ItemIterator I = Items.begin(); I != Items.end(); ++I) + if((*I)->TransactionID == TransactionID) + if((*I)->Status != pkgAcquire::Item::StatDone && + (*I)->Status != pkgAcquire::Item::StatIdle) + 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 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::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 @@ -468,7 +545,7 @@ void pkgAcquire::Bump() pkgAcquire::Worker *pkgAcquire::WorkerStep(Worker *I) { return I->NextAcquire; -}; +} /*}}}*/ // Acquire::Clean - Cleans a directory /*{{{*/ // --------------------------------------------------------------------- @@ -480,6 +557,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()); @@ -520,7 +600,7 @@ bool pkgAcquire::Clean(string Dir) // Acquire::TotalNeeded - Number of bytes to fetch /*{{{*/ // --------------------------------------------------------------------- /* This is the total number of bytes needed */ -unsigned long long pkgAcquire::TotalNeeded() +APT_PURE unsigned long long pkgAcquire::TotalNeeded() { unsigned long long Total = 0; for (ItemCIterator I = ItemsBegin(); I != ItemsEnd(); ++I) @@ -531,7 +611,7 @@ unsigned long long pkgAcquire::TotalNeeded() // Acquire::FetchNeeded - Number of bytes needed to get /*{{{*/ // --------------------------------------------------------------------- /* This is the number of bytes that is not local */ -unsigned long long pkgAcquire::FetchNeeded() +APT_PURE unsigned long long pkgAcquire::FetchNeeded() { unsigned long long Total = 0; for (ItemCIterator I = ItemsBegin(); I != ItemsEnd(); ++I) @@ -543,7 +623,7 @@ unsigned long long pkgAcquire::FetchNeeded() // Acquire::PartialPresent - Number of partial bytes we already have /*{{{*/ // --------------------------------------------------------------------- /* This is the number of bytes that is not local */ -unsigned long long pkgAcquire::PartialPresent() +APT_PURE unsigned long long pkgAcquire::PartialPresent() { unsigned long long Total = 0; for (ItemCIterator I = ItemsBegin(); I != ItemsEnd(); ++I) @@ -815,7 +895,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++; @@ -826,6 +908,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; @@ -837,6 +926,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; @@ -847,6 +937,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) @@ -857,6 +948,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; @@ -877,6 +974,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) { @@ -894,13 +999,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());