// Acquire::Item::Item - Constructor /*{{{*/
pkgAcquire::Item::Item(pkgAcquire *Owner, HashStringList const &ExpectedHashes) :
Owner(Owner), FileSize(0), PartialSize(0), Mode(0), ID(0), Complete(false),
- Local(false), QueueCounter(0), ExpectedAdditionalItems(0),
+ Local(false), QueueCounter(0), TransactionID(0), ExpectedAdditionalItems(0),
ExpectedHashes(ExpectedHashes)
{
Owner->Add(this);
* patches. If anything goes wrong in that process, it will fall back to
* the original packages file
*/
-pkgAcqDiffIndex::pkgAcqDiffIndex(pkgAcquire *Owner,
+pkgAcqDiffIndex::pkgAcqDiffIndex(pkgAcqMetaIndex *MetaOwner,
IndexTarget const * const Target,
HashStringList const &ExpectedHashes,
indexRecords *MetaIndexParser)
- : pkgAcqBaseIndex(Owner, Target, ExpectedHashes, MetaIndexParser)
+ : pkgAcqBaseIndex(MetaOwner, Target, ExpectedHashes,
+ MetaIndexParser)
{
Debug = _config->FindB("Debug::pkgAcquire::Diffs",false);
std::clog << "Package file is up-to-date" << std::endl;
// list cleanup needs to know that this file as well as the already
// present index is ours, so we create an empty diff to save it for us
- new pkgAcqIndexDiffs(Owner, Target, ExpectedHashes, MetaIndexParser,
+ new pkgAcqIndexDiffs(MetaOwner, Target, ExpectedHashes, MetaIndexParser,
ServerSha1, available_patches);
return true;
}
if (pdiff_merge == false)
{
- new pkgAcqIndexDiffs(Owner, Target, ExpectedHashes, MetaIndexParser,
+ new pkgAcqIndexDiffs(MetaOwner, Target, ExpectedHashes, MetaIndexParser,
ServerSha1, available_patches);
}
else
{
std::vector<pkgAcqIndexMergeDiffs*> *diffs = new std::vector<pkgAcqIndexMergeDiffs*>(available_patches.size());
for(size_t i = 0; i < available_patches.size(); ++i)
- (*diffs)[i] = new pkgAcqIndexMergeDiffs(Owner, Target,
+ (*diffs)[i] = new pkgAcqIndexMergeDiffs(MetaOwner, Target,
ExpectedHashes,
MetaIndexParser,
available_patches[i],
std::clog << "pkgAcqDiffIndex failed: " << Desc.URI << " with " << Message << std::endl
<< "Falling back to normal index file acquire" << std::endl;
- new pkgAcqIndex(Owner, Target, ExpectedHashes, MetaIndexParser);
+ new pkgAcqIndex(MetaOwner, Target, ExpectedHashes, MetaIndexParser);
Complete = false;
Status = StatDone;
/* The package diff is added to the queue. one object is constructed
* for each diff and the index
*/
-pkgAcqIndexDiffs::pkgAcqIndexDiffs(pkgAcquire *Owner,
+pkgAcqIndexDiffs::pkgAcqIndexDiffs(pkgAcqMetaIndex *MetaOwner,
struct IndexTarget const * const Target,
HashStringList const &ExpectedHashes,
indexRecords *MetaIndexParser,
string ServerSha1,
vector<DiffInfo> diffs)
- : pkgAcqBaseIndex(Owner, Target, ExpectedHashes, MetaIndexParser),
+ : pkgAcqBaseIndex(MetaOwner, Target, ExpectedHashes, MetaIndexParser),
available_patches(diffs), ServerSha1(ServerSha1)
{
if(Debug)
std::clog << "pkgAcqIndexDiffs failed: " << Desc.URI << " with " << Message << std::endl
<< "Falling back to normal index file acquire" << std::endl;
- new pkgAcqIndex(Owner, Target, ExpectedHashes, MetaIndexParser);
+ new pkgAcqIndex(MetaOwner, Target, ExpectedHashes, MetaIndexParser);
Finish();
}
/*}}}*/
// see if there is more to download
if(available_patches.empty() == false) {
- new pkgAcqIndexDiffs(Owner, Target,
+ new pkgAcqIndexDiffs(MetaOwner, Target,
ExpectedHashes, MetaIndexParser,
ServerSha1, available_patches);
return Finish();
}
/*}}}*/
// AcqIndexMergeDiffs::AcqIndexMergeDiffs - Constructor /*{{{*/
-pkgAcqIndexMergeDiffs::pkgAcqIndexMergeDiffs(pkgAcquire *Owner,
+pkgAcqIndexMergeDiffs::pkgAcqIndexMergeDiffs(pkgAcqMetaIndex *MetaOwner,
struct IndexTarget const * const Target,
HashStringList const &ExpectedHashes,
indexRecords *MetaIndexParser,
DiffInfo const &patch,
std::vector<pkgAcqIndexMergeDiffs*> const * const allPatches)
- : pkgAcqBaseIndex(Owner, Target, ExpectedHashes, MetaIndexParser),
+ : pkgAcqBaseIndex(MetaOwner, Target, ExpectedHashes, MetaIndexParser),
patch(patch), allPatches(allPatches), State(StateFetchDiff)
{
// first failure means we should fallback
State = StateErrorDiff;
std::clog << "Falling back to normal index file acquire" << std::endl;
- new pkgAcqIndex(Owner, Target, ExpectedHashes, MetaIndexParser);
+ new pkgAcqIndex(MetaOwner, Target, ExpectedHashes, MetaIndexParser);
}
/*}}}*/
void pkgAcqIndexMergeDiffs::Done(string Message,unsigned long long Size,HashStringList const &Hashes, /*{{{*/
}
CompressionExtension = comprExt;
- Verify = true;
-
Init(URI, URIDesc, ShortDesc);
}
+#if 0
pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner, IndexTarget const *Target,
HashStringList const &ExpectedHash,
indexRecords *MetaIndexParser)
RealURI(Target->URI)
{
// autoselect the compression method
+ AutoSelectCompression();
+ Init(Target->URI, Target->Description, Target->ShortDesc);
+}
+#endif
+ /*}}}*/
+pkgAcqIndex::pkgAcqIndex(pkgAcqMetaIndex *MetaOwner,
+ IndexTarget const *Target,
+ HashStringList const &ExpectedHash,
+ indexRecords *MetaIndexParser)
+ : pkgAcqBaseIndex(MetaOwner->GetOwner(), Target, ExpectedHash,
+ MetaIndexParser), RealURI(Target->URI)
+{
+ // autoselect the compression method
+ AutoSelectCompression();
+ Init(Target->URI, Target->Description, Target->ShortDesc);
+
+ TransactionID = (unsigned long)MetaOwner;
+}
+ /*}}}*/
+void pkgAcqIndex::AutoSelectCompression()
+{
std::vector<std::string> types = APT::Configuration::getCompressionTypes();
CompressionExtension = "";
if (ExpectedHashes.usable())
}
if (CompressionExtension.empty() == false)
CompressionExtension.erase(CompressionExtension.end()-1);
-
- // only verify non-optional targets, see acquire-item.h for a FIXME
- // to make this more flexible
- if (Target->IsOptional())
- Verify = false;
- else
- Verify = true;
-
- 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;
indexRecords::checkSum *Record = MetaIndexParser->Lookup(MetaKey);
if(Record)
FileSize = Record->Size;
+
+ InitByHashIfNeeded(MetaKey);
}
- // do the request by-hash
- if(_config->FindB("APT::Acquire::By-Hash", false) == true &&
- MetaIndexParser)
+ Desc.Description = URIDesc;
+ Desc.Owner = this;
+ Desc.ShortDesc = ShortDesc;
+
+ QueueURI(Desc);
+}
+ /*}}}*/
+// AcqIndex::AdjustForByHash - modify URI for by-hash support /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void pkgAcqIndex::InitByHashIfNeeded(const std::string MetaKey)
+{
+ // TODO:
+ // - (maybe?) add support for by-hash into the sources.list as flag
+ // - make apt-ftparchive generate the hashes (and expire?)
+ std::string HostKnob = "APT::Acquire::" + ::URI(Desc.URI).Host + "::By-Hash";
+ if(_config->FindB("APT::Acquire::By-Hash", false) == true ||
+ _config->FindB(HostKnob, false) == true ||
+ MetaIndexParser->GetSupportsAcquireByHash())
{
indexRecords::checkSum *Record = MetaIndexParser->Lookup(MetaKey);
if(Record)
{
- // FIXME: make the hash used a config option or read from release file
- const HashString *TargetHash = Record->Hashes.find("SHA256");
- std::string ByHash = "/by-hash/" + TargetHash->HashValue();
+ // FIXME: should we really use the best hash here? or a fixed one?
+ const HashString *TargetHash = Record->Hashes.find("");
+ std::string ByHash = "/by-hash/" + TargetHash->HashType() + "/" + TargetHash->HashValue();
size_t trailing_slash = Desc.URI.find_last_of("/");
- Desc.URI = Desc.URI.replace(trailing_slash,
- Desc.URI.substr(trailing_slash+1).size()+1,
- ByHash);
- std::cerr << Desc.URI << std::endl;
+ Desc.URI = Desc.URI.replace(
+ trailing_slash,
+ Desc.URI.substr(trailing_slash+1).size()+1,
+ ByHash);
} else {
- _error->Warning("By-Hash requested but can not find record for %s",
- MetaKey.c_str());
+ _error->Warning(
+ "Fetching ByHash requested but can not find record for %s",
+ MetaKey.c_str());
}
}
-
- Desc.Description = URIDesc;
- Desc.Owner = this;
- Desc.ShortDesc = ShortDesc;
-
- QueueURI(Desc);
}
/*}}}*/
// AcqIndex::Custom600Headers - Insert custom request headers /*{{{*/
}
Item::Failed(Message,Cnf);
+
+ /// cancel the entire transaction
+ Owner->AbortTransaction(TransactionID);
}
/*}}}*/
// AcqIndex::Done - Finished a fetch /*{{{*/
{
RenameOnError(HashSumMismatch);
printHashSumComparision(RealURI, ExpectedHashes, Hashes);
+ Failed(Message, Cfg);
return;
}
- /* Verify the index file for correctness (all indexes must
- * have a Package field) (LP: #346386) (Closes: #627642) */
- if (Verify == true)
+ // FIXME: this can go away once we only ever download stuff that
+ // has a valid hash and we never do GET based probing
+ //
+ /* Always verify the index file for correctness (all indexes must
+ * have a Package field) (LP: #346386) (Closes: #627642)
+ */
+ FileFd fd(DestFile, FileFd::ReadOnly);
+ // Only test for correctness if the file is not empty (empty is ok)
+ if (fd.FileSize() > 0)
{
- FileFd fd(DestFile, FileFd::ReadOnly);
- // Only test for correctness if the file is not empty (empty is ok)
- if (fd.FileSize() > 0)
- {
- pkgTagSection sec;
- pkgTagFile tag(&fd);
-
- // all our current indexes have a field 'Package' in each section
- if (_error->PendingError() == true || tag.Step(sec) == false || sec.Exists("Package") == false)
- {
- RenameOnError(InvalidFormat);
- return;
- }
+ pkgTagSection sec;
+ pkgTagFile tag(&fd);
+
+ // all our current indexes have a field 'Package' in each section
+ if (_error->PendingError() == true || tag.Step(sec) == false || sec.Exists("Package") == false)
+ {
+ RenameOnError(InvalidFormat);
+ Failed(Message, Cfg);
+ return;
}
}
- // Done, move it into position
+ // Done, queue for rename on transaction finished
+ PartialFile = DestFile;
+
string FinalFile = _config->FindDir("Dir::State::lists");
FinalFile += URItoFileName(RealURI);
- Rename(DestFile,FinalFile);
- chmod(FinalFile.c_str(),0644);
-
+ DestFile = FinalFile;
+#if 0
/* We restore the original name to DestFile so that the clean operation
will work OK */
DestFile = _config->FindDir("Dir::State::lists") + "partial/";
// Remove the compressed version.
if (Erase == true)
unlink(DestFile.c_str());
-
+#endif
return;
}
: pkgAcqIndex(Owner, URI, URIDesc, ShortDesc, HashStringList(), "")
{
}
-pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcquire *Owner, IndexTarget const * const Target,
+ /*}}}*/
+pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcqMetaIndex *MetaOwner, IndexTarget const * const Target,
HashStringList const &ExpectedHashes, indexRecords *MetaIndexParser)
- : pkgAcqIndex(Owner, Target, ExpectedHashes, MetaIndexParser)
+ : pkgAcqIndex(MetaOwner, Target, ExpectedHashes, MetaIndexParser)
{
// load the filesize
indexRecords::checkSum *Record = MetaIndexParser->Lookup(string(Target->MetaKey));
if(StringToBool(LookupTag(Message,"IMS-Hit"),false) == true)
Rename(LastGoodSig, DestFile);
+ // queue for copy
+ PartialFile = DestFile;
+ DestFile = _config->FindDir("Dir::State::lists");
+ DestFile += URItoFileName(RealURI);
+
// queue a pkgAcqMetaIndex to be verified against the sig we just retrieved
- new pkgAcqMetaIndex(Owner, MetaIndexURI, MetaIndexURIDesc,
- MetaIndexShortDesc, DestFile, IndexTargets,
- MetaIndexParser);
+ pkgAcqMetaIndex *metaindex = new pkgAcqMetaIndex(
+ Owner, MetaIndexURI, MetaIndexURIDesc,
+ MetaIndexShortDesc, DestFile, IndexTargets,
+ MetaIndexParser);
+ TransactionID = (unsigned long)metaindex;
}
/*}}}*/
void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf)/*{{{*/
DestFile = _config->FindDir("Dir::State::lists") + "partial/";
DestFile += URItoFileName(URI);
+ TransactionID = (unsigned long)this;
+
// Create the item
Desc.Description = URIDesc;
Desc.Owner = this;
FinalFile += URItoFileName(RealURI);
if (SigFile == DestFile)
SigFile = FinalFile;
- Rename(DestFile,FinalFile);
- chmod(FinalFile.c_str(),0644);
+ PartialFile = DestFile;
DestFile = FinalFile;
}
}
// Download further indexes with verification
QueueIndexes(true);
+#if 0
// is it a clearsigned MetaIndex file?
if (DestFile == SigFile)
return;
URItoFileName(RealURI) + ".gpg";
Rename(SigFile,VerifiedSigFile);
chmod(VerifiedSigFile.c_str(),0644);
+#endif
}
/*}}}*/
void pkgAcqMetaIndex::QueueIndexes(bool verify) /*{{{*/
// at this point the real Items are loaded in the fetcher
ExpectedAdditionalItems = 0;
-
for (vector <IndexTarget*>::const_iterator Target = IndexTargets->begin();
Target != IndexTargets->end();
++Target)
{
if (_config->FindB("Acquire::PDiffs",true) == true && transInRelease == true &&
MetaIndexParser->Exists((*Target)->MetaKey + ".diff/Index") == true)
- new pkgAcqDiffIndex(Owner, *Target, ExpectedIndexHashes, MetaIndexParser);
+ new pkgAcqDiffIndex(this, *Target, ExpectedIndexHashes, MetaIndexParser);
else
- new pkgAcqIndexTrans(Owner, *Target, ExpectedIndexHashes, MetaIndexParser);
+ new pkgAcqIndexTrans(this, *Target, ExpectedIndexHashes, MetaIndexParser);
}
continue;
}
instead, but passing the required info to it is to much hassle */
if(_config->FindB("Acquire::PDiffs",true) == true && (verify == false ||
MetaIndexParser->Exists((*Target)->MetaKey + ".diff/Index") == true))
- new pkgAcqDiffIndex(Owner, *Target, ExpectedIndexHashes, MetaIndexParser);
+ new pkgAcqDiffIndex(this, *Target, ExpectedIndexHashes, MetaIndexParser);
else
- new pkgAcqIndex(Owner, *Target, ExpectedIndexHashes, MetaIndexParser);
+ new pkgAcqIndex(this, *Target, ExpectedIndexHashes, MetaIndexParser);
}
}
/*}}}*/
// pkgAcqMetaIndex::Failed - no Release file present or no signature file present /*{{{*/
// ---------------------------------------------------------------------
/* */
-void pkgAcqMetaIndex::Failed(string Message,pkgAcquire::MethodConfig * /*Cnf*/)
+void pkgAcqMetaIndex::Failed(string /*Message*/,
+ pkgAcquire::MethodConfig * /*Cnf*/)
{
+#if 0
if (AuthPass == true)
{
// gpgv method failed, if we have a good signature
// gpgv method failed
ReportMirrorFailure("GPGFailure");
}
-
+#endif
/* Always move the meta index, even if gpgv failed. This ensures
* that PackageFile objects are correctly filled in */
if (FileExists(DestFile)) {
QueueIndexes(false);
}
/*}}}*/
+
+void pkgAcqMetaIndex::Finished()
+{
+ if(_config->FindB("Debug::Acquire::Transaction", false) == true)
+ std::clog << "Finished: " << DestFile <<std::endl;
+ if(Owner->TransactionHasError((unsigned long)this) == false)
+ Owner->CommitTransaction((unsigned long)this);
+}
+
+
pkgAcqMetaClearSig::pkgAcqMetaClearSig(pkgAcquire *Owner, /*{{{*/
string const &URI, string const &URIDesc, string const &ShortDesc,
string const &MetaIndexURI, string const &MetaIndexURIDesc, string const &MetaIndexShortDesc,