X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/70b3d263556241a0cb8217006f4dbef1138de25d..4a3b5e9d609ad7c5437fa34c20f8404d07f8d11b:/apt-pkg/acquire-item.cc diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 679f9cee7..d2aca597e 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -15,6 +15,7 @@ // Include Files /*{{{*/ #include #include +#include #include #include #include @@ -131,9 +132,7 @@ void pkgAcquire::Item::Rename(string From,string To) } } /*}}}*/ - - -// AcqDiffIndex::AcqDiffIndex - Constructor +// AcqDiffIndex::AcqDiffIndex - Constructor /*{{{*/ // --------------------------------------------------------------------- /* Get the DiffIndex file first and see if there are patches availabe * If so, create a pkgAcqIndexDiffs fetcher that will get and apply the @@ -184,7 +183,7 @@ pkgAcqDiffIndex::pkgAcqDiffIndex(pkgAcquire *Owner, QueueURI(Desc); } - + /*}}}*/ // AcqIndex::Custom600Headers - Insert custom request headers /*{{{*/ // --------------------------------------------------------------------- /* The only header we use is the last-modified header. */ @@ -202,9 +201,8 @@ string pkgAcqDiffIndex::Custom600Headers() return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime); } - - -bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile) + /*}}}*/ +bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile) /*{{{*/ { if(Debug) std::clog << "pkgAcqIndexDiffs::ParseIndexDiff() " << IndexDiffFile @@ -221,19 +219,19 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile) if(TF.Step(Tags) == true) { - string local_sha1; bool found = false; DiffInfo d; string size; - string tmp = Tags.FindS("SHA1-Current"); + string const tmp = Tags.FindS("SHA1-Current"); std::stringstream ss(tmp); - ss >> ServerSha1; + ss >> ServerSha1 >> size; + unsigned long const ServerSize = atol(size.c_str()); FileFd fd(CurrentPackagesFile, FileFd::ReadOnly); SHA1Summation SHA1; SHA1.AddFD(fd.Fd(), fd.Size()); - local_sha1 = string(SHA1.Result()); + string const local_sha1 = SHA1.Result(); if(local_sha1 == ServerSha1) { @@ -250,20 +248,56 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile) std::clog << "SHA1-Current: " << ServerSha1 << std::endl; // check the historie and see what patches we need - string history = Tags.FindS("SHA1-History"); + string const history = Tags.FindS("SHA1-History"); std::stringstream hist(history); - while(hist >> d.sha1 >> size >> d.file) + while(hist >> d.sha1 >> size >> d.file) { - d.size = atoi(size.c_str()); // read until the first match is found + // from that point on, we probably need all diffs if(d.sha1 == local_sha1) found=true; - // from that point on, we probably need all diffs - if(found) + else if (found == false) + continue; + + if(Debug) + std::clog << "Need to get diff: " << d.file << std::endl; + available_patches.push_back(d); + } + + if (available_patches.empty() == false) + { + // patching with too many files is rather slow compared to a fast download + unsigned long const fileLimit = _config->FindI("Acquire::PDiffs::FileLimit", 0); + if (fileLimit != 0 && fileLimit < available_patches.size()) + { + if (Debug) + std::clog << "Need " << available_patches.size() << " diffs (Limit is " << fileLimit + << ") so fallback to complete download" << std::endl; + return false; + } + + // see if the patches are too big + found = false; // it was true and it will be true again at the end + d = *available_patches.begin(); + string const firstPatch = d.file; + unsigned long patchesSize = 0; + std::stringstream patches(Tags.FindS("SHA1-Patches")); + while(patches >> d.sha1 >> size >> d.file) { - if(Debug) - std::clog << "Need to get diff: " << d.file << std::endl; - available_patches.push_back(d); + if (firstPatch == d.file) + found = true; + else if (found == false) + continue; + + patchesSize += atol(size.c_str()); + } + unsigned long const sizeLimit = ServerSize * _config->FindI("Acquire::PDiffs::SizeLimit", 100); + if (sizeLimit > 0 && (sizeLimit/100) < patchesSize) + { + if (Debug) + std::clog << "Need " << patchesSize << " bytes (Limit is " << sizeLimit/100 + << ") so fallback to complete download" << std::endl; + return false; } } } @@ -272,7 +306,7 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile) if(found) { // queue the diffs - string::size_type last_space = Description.rfind(" "); + string::size_type const last_space = Description.rfind(" "); if(last_space != string::npos) Description.erase(last_space, Description.size()-last_space); new pkgAcqIndexDiffs(Owner, RealURI, Description, Desc.ShortDesc, @@ -291,8 +325,8 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile) std::clog << "Can't find a patch in the index file" << std::endl; return false; } - -void pkgAcqDiffIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf) + /*}}}*/ +void pkgAcqDiffIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*{{{*/ { if(Debug) std::clog << "pkgAcqDiffIndex failed: " << Desc.URI << std::endl @@ -305,8 +339,8 @@ void pkgAcqDiffIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf) Status = StatDone; Dequeue(); } - -void pkgAcqDiffIndex::Done(string Message,unsigned long Size,string Md5Hash, + /*}}}*/ +void pkgAcqDiffIndex::Done(string Message,unsigned long Size,string Md5Hash, /*{{{*/ pkgAcquire::MethodConfig *Cnf) { if(Debug) @@ -335,10 +369,8 @@ void pkgAcqDiffIndex::Done(string Message,unsigned long Size,string Md5Hash, Dequeue(); return; } - - - -// AcqIndexDiffs::AcqIndexDiffs - Constructor + /*}}}*/ +// AcqIndexDiffs::AcqIndexDiffs - Constructor /*{{{*/ // --------------------------------------------------------------------- /* The package diff is added to the queue. one object is constructed * for each diff and the index @@ -372,9 +404,8 @@ pkgAcqIndexDiffs::pkgAcqIndexDiffs(pkgAcquire *Owner, QueueNextDiff(); } } - - -void pkgAcqIndexDiffs::Failed(string Message,pkgAcquire::MethodConfig *Cnf) + /*}}}*/ +void pkgAcqIndexDiffs::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*{{{*/ { if(Debug) std::clog << "pkgAcqIndexDiffs failed: " << Desc.URI << std::endl @@ -383,9 +414,8 @@ void pkgAcqIndexDiffs::Failed(string Message,pkgAcquire::MethodConfig *Cnf) ExpectedHash); Finish(); } - - -// helper that cleans the item out of the fetcher queue + /*}}}*/ +// Finish - helper that cleans the item out of the fetcher queue /*{{{*/ void pkgAcqIndexDiffs::Finish(bool allDone) { // we restore the original name, this is required, otherwise @@ -420,10 +450,8 @@ void pkgAcqIndexDiffs::Finish(bool allDone) Dequeue(); return; } - - - -bool pkgAcqIndexDiffs::QueueNextDiff() + /*}}}*/ +bool pkgAcqIndexDiffs::QueueNextDiff() /*{{{*/ { // calc sha1 of the just patched file @@ -469,10 +497,8 @@ bool pkgAcqIndexDiffs::QueueNextDiff() return true; } - - - -void pkgAcqIndexDiffs::Done(string Message,unsigned long Size,string Md5Hash, + /*}}}*/ +void pkgAcqIndexDiffs::Done(string Message,unsigned long Size,string Md5Hash, /*{{{*/ pkgAcquire::MethodConfig *Cnf) { if(Debug) @@ -543,8 +569,7 @@ void pkgAcqIndexDiffs::Done(string Message,unsigned long Size,string Md5Hash, return Finish(true); } } - - + /*}}}*/ // AcqIndex::AcqIndex - Constructor /*{{{*/ // --------------------------------------------------------------------- /* The package file is added to the queue and a second class is @@ -563,13 +588,14 @@ pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner, if(comprExt.empty()) { // autoselect the compression method - if(FileExists("/bin/bzip2")) - CompressionExtension = ".bz2"; - else - CompressionExtension = ".gz"; - } else { - CompressionExtension = (comprExt == "plain" ? "" : comprExt); + std::vector types = APT::Configuration::getCompressionTypes(); + if (types.empty() == true) + comprExt = "plain"; + else + comprExt = "." + types[0]; } + CompressionExtension = ((comprExt == "plain" || comprExt == ".") ? "" : comprExt); + Desc.URI = URI + CompressionExtension; Desc.Description = URIDesc; @@ -594,27 +620,29 @@ string pkgAcqIndex::Custom600Headers() return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime); } /*}}}*/ - -void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf) +void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*{{{*/ { - bool descChanged = false; - // no .bz2 found, retry with .gz - if(Desc.URI.substr(Desc.URI.size()-3) == "bz2") { - Desc.URI = Desc.URI.substr(0,Desc.URI.size()-3) + "gz"; - - new pkgAcqIndex(Owner, RealURI, Desc.Description,Desc.ShortDesc, - ExpectedHash, string(".gz")); - descChanged = true; - } - // no .gz found, retry with uncompressed - else if(Desc.URI.substr(Desc.URI.size()-2) == "gz") { - Desc.URI = Desc.URI.substr(0,Desc.URI.size()-2); + std::vector types = APT::Configuration::getCompressionTypes(); - new pkgAcqIndex(Owner, RealURI, Desc.Description,Desc.ShortDesc, - ExpectedHash, string("plain")); - descChanged = true; - } - if (descChanged) { + for (std::vector::const_iterator t = types.begin(); + t != types.end(); t++) + { + // jump over all already tried compression types + const unsigned int nameLen = Desc.URI.size() - (*t).size(); + if(Desc.URI.substr(nameLen) != *t) + continue; + + // we want to try it with the next extension (and make sure to + // not skip over the end) + t++; + if (t == types.end()) + break; + + // queue new download + Desc.URI = Desc.URI.substr(0, nameLen) + *t; + new pkgAcqIndex(Owner, RealURI, Desc.Description, Desc.ShortDesc, + ExpectedHash, string(".").append(*t)); + Status = StatDone; Complete = false; Dequeue(); @@ -630,8 +658,7 @@ void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf) Item::Failed(Message,Cnf); } - - + /*}}}*/ // AcqIndex::Done - Finished a fetch /*{{{*/ // --------------------------------------------------------------------- /* This goes through a number of states.. On the initial fetch the @@ -711,13 +738,18 @@ void pkgAcqIndex::Done(string Message,unsigned long Size,string Hash, else Local = true; - string compExt = flExtension(URI(Desc.URI).Path); - const char *decompProg; - if(compExt == "bz2") - decompProg = "bzip2"; - else if(compExt == ".gz") - decompProg = "gzip"; - else if(compExt == "") + string compExt = flExtension(flNotDir(URI(Desc.URI).Path)); + string decompProg; + + // get the binary name for your used compression type + decompProg = _config->Find(string("Acquire::CompressionTypes::").append(compExt),""); + if(decompProg.empty() == false); + // flExtensions returns the full name if no extension is found + // this is why we have this complicated compare operation here + // FIMXE: add a new flJustExtension() that return "" if no + // extension is found and use that above so that it can + // be tested against "" + else if(compExt == flNotDir(URI(Desc.URI).Path)) decompProg = "copy"; else { _error->Error("Unsupported extension: %s", compExt.c_str()); @@ -726,11 +758,11 @@ void pkgAcqIndex::Done(string Message,unsigned long Size,string Hash, Decompression = true; DestFile += ".decomp"; - Desc.URI = string(decompProg) + ":" + FileName; + Desc.URI = decompProg + ":" + FileName; QueueURI(Desc); - Mode = decompProg; + Mode = decompProg.c_str(); } - + /*}}}*/ // AcqIndexTrans::pkgAcqIndexTrans - Constructor /*{{{*/ // --------------------------------------------------------------------- /* The Translation file is added to the queue */ @@ -739,7 +771,6 @@ pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcquire *Owner, : pkgAcqIndex(Owner, URI, URIDesc, ShortDesc, HashString(), "") { } - /*}}}*/ // AcqIndexTrans::Failed - Silence failure messages for missing files /*{{{*/ // --------------------------------------------------------------------- @@ -759,8 +790,7 @@ void pkgAcqIndexTrans::Failed(string Message,pkgAcquire::MethodConfig *Cnf) Item::Failed(Message,Cnf); } /*}}}*/ - -pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire *Owner, +pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire *Owner, /*{{{*/ string URI,string URIDesc,string ShortDesc, string MetaIndexURI, string MetaIndexURIDesc, string MetaIndexShortDesc, @@ -849,7 +879,7 @@ void pkgAcqMetaSig::Done(string Message,unsigned long Size,string MD5, } /*}}}*/ -void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf) +void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf)/*{{{*/ { string Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI); @@ -885,8 +915,8 @@ void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf) Item::Failed(Message,Cnf); } - -pkgAcqMetaIndex::pkgAcqMetaIndex(pkgAcquire *Owner, + /*}}}*/ +pkgAcqMetaIndex::pkgAcqMetaIndex(pkgAcquire *Owner, /*{{{*/ string URI,string URIDesc,string ShortDesc, string SigFile, const vector* IndexTargets, @@ -905,7 +935,6 @@ pkgAcqMetaIndex::pkgAcqMetaIndex(pkgAcquire *Owner, QueueURI(Desc); } - /*}}}*/ // pkgAcqMetaIndex::Custom600Headers - Insert custom request headers /*{{{*/ // --------------------------------------------------------------------- @@ -921,8 +950,8 @@ string pkgAcqMetaIndex::Custom600Headers() return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime); } - -void pkgAcqMetaIndex::Done(string Message,unsigned long Size,string Hash, + /*}}}*/ +void pkgAcqMetaIndex::Done(string Message,unsigned long Size,string Hash, /*{{{*/ pkgAcquire::MethodConfig *Cfg) { Item::Done(Message,Size,Hash,Cfg); @@ -963,8 +992,8 @@ void pkgAcqMetaIndex::Done(string Message,unsigned long Size,string Hash, } } } - -void pkgAcqMetaIndex::RetrievalDone(string Message) + /*}}}*/ +void pkgAcqMetaIndex::RetrievalDone(string Message) /*{{{*/ { // We have just finished downloading a Release file (it is not // verified yet) @@ -1002,8 +1031,8 @@ void pkgAcqMetaIndex::RetrievalDone(string Message) chmod(FinalFile.c_str(),0644); DestFile = FinalFile; } - -void pkgAcqMetaIndex::AuthDone(string Message) + /*}}}*/ +void pkgAcqMetaIndex::AuthDone(string Message) /*{{{*/ { // At this point, the gpgv method has succeeded, so there is a // valid signature from a key in the trusted keyring. We @@ -1036,8 +1065,8 @@ void pkgAcqMetaIndex::AuthDone(string Message) Rename(SigFile,VerifiedSigFile); chmod(VerifiedSigFile.c_str(),0644); } - -void pkgAcqMetaIndex::QueueIndexes(bool verify) + /*}}}*/ +void pkgAcqMetaIndex::QueueIndexes(bool verify) /*{{{*/ { for (vector ::const_iterator Target = IndexTargets->begin(); Target != IndexTargets->end(); @@ -1079,8 +1108,8 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify) (*Target)->ShortDesc, ExpectedIndexHash); } } - -bool pkgAcqMetaIndex::VerifyVendor(string Message) + /*}}}*/ +bool pkgAcqMetaIndex::VerifyVendor(string Message) /*{{{*/ { // // Maybe this should be made available from above so we don't have // // to read and parse it every time? @@ -1166,9 +1195,8 @@ bool pkgAcqMetaIndex::VerifyVendor(string Message) return true; } - /*}}}*/ -// pkgAcqMetaIndex::Failed - no Release file present or no signature -// file present /*{{{*/ + /*}}}*/ +// pkgAcqMetaIndex::Failed - no Release file present or no signature file present /*{{{*/ // --------------------------------------------------------------------- /* */ void pkgAcqMetaIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf) @@ -1205,9 +1233,7 @@ void pkgAcqMetaIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf) // back to queueing Packages files without verification QueueIndexes(false); } - /*}}}*/ - // AcqArchive::AcqArchive - Constructor /*{{{*/ // --------------------------------------------------------------------- /* This just sets up the initial fetch environment and queues the first @@ -1490,14 +1516,13 @@ void pkgAcqArchive::Failed(string Message,pkgAcquire::MethodConfig *Cnf) } } /*}}}*/ -// AcqArchive::IsTrusted - Determine whether this archive comes from a -// trusted source /*{{{*/ +// AcqArchive::IsTrusted - Determine whether this archive comes from a trusted source /*{{{*/ // --------------------------------------------------------------------- bool pkgAcqArchive::IsTrusted() { return Trusted; } - + /*}}}*/ // AcqArchive::Finished - Fetching has finished, tidy up /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -1509,7 +1534,6 @@ void pkgAcqArchive::Finished() StoreFilename = string(); } /*}}}*/ - // AcqFile::pkgAcqFile - Constructor /*{{{*/ // --------------------------------------------------------------------- /* The file is added to the queue */