+ // success in download/apply a diff, queue next (if needed)
+ if(State == StateApplyDiff)
+ {
+ // remove the just applied patch
+ available_patches.erase(available_patches.begin());
+
+ // move into place
+ if(Debug)
+ {
+ std::clog << "Moving patched file in place: " << std::endl
+ << DestFile << " -> " << FinalFile << std::endl;
+ }
+ Rename(DestFile,FinalFile);
+ chmod(FinalFile.c_str(),0644);
+
+ // see if there is more to download
+ if(available_patches.size() > 0) {
+ new pkgAcqIndexDiffs(Owner, RealURI, Description, Desc.ShortDesc,
+ ExpectedHash, ServerSha1, available_patches);
+ return Finish();
+ } else
+ return Finish(true);
+ }
+}
+ /*}}}*/
+// AcqIndex::AcqIndex - Constructor /*{{{*/
+// ---------------------------------------------------------------------
+/* The package file is added to the queue and a second class is
+ instantiated to fetch the revision file */
+pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,
+ string URI,string URIDesc,string ShortDesc,
+ HashString ExpectedHash, string comprExt)
+ : Item(Owner), RealURI(URI), ExpectedHash(ExpectedHash)
+{
+ if(comprExt.empty() == true)
+ {
+ // autoselect the compression method
+ std::vector<std::string> types = APT::Configuration::getCompressionTypes();
+ for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
+ comprExt.append(*t).append(" ");
+ if (comprExt.empty() == false)
+ comprExt.erase(comprExt.end()-1);
+ }
+ CompressionExtension = comprExt;
+
+ Init(URI, URIDesc, ShortDesc);
+}
+pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner, IndexTarget const *Target,
+ HashString const &ExpectedHash, indexRecords const *MetaIndexParser)
+ : Item(Owner), RealURI(Target->URI), ExpectedHash(ExpectedHash)
+{
+ // autoselect the compression method
+ std::vector<std::string> types = APT::Configuration::getCompressionTypes();
+ CompressionExtension = "";
+ if (ExpectedHash.empty() == false)
+ {
+ for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
+ if (*t == "uncompressed" || MetaIndexParser->Exists(string(Target->MetaKey).append(".").append(*t)) == true)
+ CompressionExtension.append(*t).append(" ");
+ }
+ else
+ {
+ for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
+ CompressionExtension.append(*t).append(" ");
+ }
+ if (CompressionExtension.empty() == false)
+ CompressionExtension.erase(CompressionExtension.end()-1);
+
+ Init(Target->URI, Target->Description, Target->ShortDesc);
+}
+ /*}}}*/
+// AcqIndex::Init - defered Constructor /*{{{*/
+void pkgAcqIndex::Init(string const &URI, string const &URIDesc, string const &ShortDesc) {
+ Decompression = false;
+ Erase = false;
+
+ DestFile = _config->FindDir("Dir::State::lists") + "partial/";
+ DestFile += URItoFileName(URI);
+
+ std::string const comprExt = CompressionExtension.substr(0, CompressionExtension.find(' '));
+ if (comprExt == "uncompressed")
+ Desc.URI = URI;
+ else
+ Desc.URI = URI + '.' + comprExt;
+
+ Desc.Description = URIDesc;
+ Desc.Owner = this;
+ Desc.ShortDesc = ShortDesc;
+
+ QueueURI(Desc);
+}
+ /*}}}*/
+// AcqIndex::Custom600Headers - Insert custom request headers /*{{{*/
+// ---------------------------------------------------------------------
+/* The only header we use is the last-modified header. */
+string pkgAcqIndex::Custom600Headers()
+{
+ string Final = _config->FindDir("Dir::State::lists");
+ Final += URItoFileName(RealURI);
+ if (_config->FindB("Acquire::GzipIndexes",false))
+ Final += ".gz";
+
+ string msg = "\nIndex-File: true";
+ // FIXME: this really should use "IndexTarget::IsOptional()" but that
+ // seems to be difficult without breaking ABI
+ if (ShortDesc().find("Translation") != 0)
+ msg += "\nFail-Ignore: true";
+ struct stat Buf;
+ if (stat(Final.c_str(),&Buf) != 0)
+ msg += "\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
+
+ return msg;
+}
+ /*}}}*/
+void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*{{{*/
+{
+ size_t const nextExt = CompressionExtension.find(' ');
+ if (nextExt != std::string::npos)
+ {
+ CompressionExtension = CompressionExtension.substr(nextExt+1);
+ Init(RealURI, Desc.Description, Desc.ShortDesc);
+ return;
+ }
+
+ // on decompression failure, remove bad versions in partial/
+ if (Decompression && Erase) {
+ string s = _config->FindDir("Dir::State::lists") + "partial/";
+ s.append(URItoFileName(RealURI));
+ unlink(s.c_str());
+ }
+
+ Item::Failed(Message,Cnf);
+}
+ /*}}}*/