X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/c8a4ce6cbed57ae108dc955d4a850f9b129a0693..921a962611dfbca7a72b2aa5c499b139dd27ae14:/apt-pkg/acquire-item.cc?ds=inline diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 3313aaabc..b6b6d8e48 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -22,9 +22,8 @@ #include #include #include -#include #include -#include +#include #include #include #include @@ -33,6 +32,7 @@ #include #include +#include #include #include #include @@ -42,9 +42,9 @@ #include #include #include -#include #include #include +#include #include /*}}}*/ @@ -80,18 +80,33 @@ static std::string GetFinalFileNameFromURI(std::string const &uri) /*{{{*/ return _config->FindDir("Dir::State::lists") + URItoFileName(uri); } /*}}}*/ -static std::string GetCompressedFileName(std::string const &URI, std::string const &Name, std::string const &Ext) /*{{{*/ +static std::string GetKeepCompressedFileName(std::string file, IndexTarget const &Target)/*{{{*/ +{ + if (Target.KeepCompressed == false) + return file; + + std::string const CompressionTypes = Target.Option(IndexTarget::COMPRESSIONTYPES); + if (CompressionTypes.empty() == false) + { + std::string const ext = CompressionTypes.substr(0, CompressionTypes.find(' ')); + if (ext != "uncompressed") + file.append(".").append(ext); + } + return file; +} + /*}}}*/ +static std::string GetCompressedFileName(IndexTarget const &Target, std::string const &Name, std::string const &Ext) /*{{{*/ { if (Ext.empty() || Ext == "uncompressed") return Name; // do not reverify cdrom sources as apt-cdrom may rewrite the Packages // file when its doing the indexcopy - if (URI.substr(0,6) == "cdrom:") + if (Target.URI.substr(0,6) == "cdrom:") return Name; // adjust DestFile if its compressed on disk - if (_config->FindB("Acquire::GzipIndexes",false) == true) + if (Target.KeepCompressed == true) return Name + '.' + Ext; return Name; } @@ -108,10 +123,34 @@ static std::string GetDiffsPatchFileName(std::string const &Final) /*{{{*/ return Final + ".ed"; } /*}}}*/ +static bool BootstrapPDiffWith(std::string const &PartialFile, std::string const &FinalFile, IndexTarget const &Target)/*{{{*/ +{ + // patching needs to be bootstrapped with the 'old' version + std::vector types = VectorizeString(Target.Option(IndexTarget::COMPRESSIONTYPES), ' '); + auto typeItr = types.cbegin(); + for (; typeItr != types.cend(); ++typeItr) + { + std::string Final = FinalFile; + if (*typeItr != "uncompressed") + Final.append(".").append(*typeItr); + if (RealFileExists(Final) == false) + continue; + std::string Partial = PartialFile; + if (*typeItr != "uncompressed") + Partial.append(".").append(*typeItr); + if (FileExists(Partial.c_str()) == true) + return true; + if (symlink(Final.c_str(), Partial.c_str()) != 0) + return false; + break; + } + return typeItr != types.cend(); +} + /*}}}*/ -static bool AllowInsecureRepositories(indexRecords const * const MetaIndexParser, pkgAcqMetaBase * const TransactionManager, pkgAcquire::Item * const I) /*{{{*/ +static bool AllowInsecureRepositories(metaIndex const * const MetaIndexParser, pkgAcqMetaClearSig * const TransactionManager, pkgAcquire::Item * const I) /*{{{*/ { - if(MetaIndexParser->IsAlwaysTrusted() || _config->FindB("Acquire::AllowInsecureRepositories") == true) + if(MetaIndexParser->GetTrusted() == metaIndex::TRI_YES || _config->FindB("Acquire::AllowInsecureRepositories") == true) return true; _error->Error(_("Use --allow-insecure-repositories to force the update")); @@ -120,11 +159,11 @@ static bool AllowInsecureRepositories(indexRecords const * const MetaIndexParser return false; } /*}}}*/ -static HashStringList GetExpectedHashesFromFor(indexRecords * const Parser, std::string const MetaKey)/*{{{*/ +static HashStringList GetExpectedHashesFromFor(metaIndex * const Parser, std::string const &MetaKey)/*{{{*/ { if (Parser == NULL) return HashStringList(); - indexRecords::checkSum * const R = Parser->Lookup(MetaKey); + metaIndex::checkSum * const R = Parser->Lookup(MetaKey); if (R == NULL) return HashStringList(); return R->Hashes; @@ -144,7 +183,8 @@ APT_CONST bool pkgAcqTransactionItem::HashesRequired() const we can at least trust them for integrity of the download itself. Only repositories without a Release file can (obviously) not have hashes – and they are very uncommon and strongly discouraged */ - return TransactionManager->MetaIndexParser != NULL; + return TransactionManager->MetaIndexParser != NULL && + TransactionManager->MetaIndexParser->GetLoadedSuccessfully() != metaIndex::TRI_UNSET; } HashStringList pkgAcqTransactionItem::GetExpectedHashes() const { @@ -268,7 +308,7 @@ std::string pkgAcqDiffIndex::GetFinalFilename() const std::string pkgAcqIndex::GetFinalFilename() const { std::string const FinalFile = GetFinalFileNameFromURI(Target.URI); - return GetCompressedFileName(Target.URI, FinalFile, CurrentCompressionExtension); + return GetCompressedFileName(Target, FinalFile, CurrentCompressionExtension); } std::string pkgAcqMetaSig::GetFinalFilename() const { @@ -390,23 +430,29 @@ class APT_HIDDEN NoActionItem : public pkgAcquire::Item /*{{{*/ { IndexTarget const Target; public: - virtual std::string DescURI() const {return Target.URI;}; - virtual HashStringList GetExpectedHashes() const {return HashStringList();}; + virtual std::string DescURI() const APT_OVERRIDE {return Target.URI;}; + virtual HashStringList GetExpectedHashes() const APT_OVERRIDE {return HashStringList();}; - NoActionItem(pkgAcquire * const Owner, IndexTarget const Target) : + NoActionItem(pkgAcquire * const Owner, IndexTarget const &Target) : pkgAcquire::Item(Owner), Target(Target) { Status = StatDone; DestFile = GetFinalFileNameFromURI(Target.URI); } + NoActionItem(pkgAcquire * const Owner, IndexTarget const &Target, std::string const &FinalFile) : + pkgAcquire::Item(Owner), Target(Target) + { + Status = StatDone; + DestFile = FinalFile; + } }; /*}}}*/ // Acquire::Item::Item - Constructor /*{{{*/ APT_IGNORE_DEPRECATED_PUSH -pkgAcquire::Item::Item(pkgAcquire * const Owner) : +pkgAcquire::Item::Item(pkgAcquire * const owner) : FileSize(0), PartialSize(0), Mode(0), ID(0), Complete(false), Local(false), - QueueCounter(0), ExpectedAdditionalItems(0), Owner(Owner) + QueueCounter(0), ExpectedAdditionalItems(0), Owner(owner), d(NULL) { Owner->Add(this); Status = StatIdle; @@ -456,7 +502,6 @@ void pkgAcquire::Item::Failed(string const &Message,pkgAcquire::MethodConfig con { if(ErrorText.empty()) ErrorText = LookupTag(Message,"Message"); - UsedMirror = LookupTag(Message,"UsedMirror"); if (QueueCounter <= 1) { /* This indicates that the file is not available right now but might @@ -514,12 +559,28 @@ void pkgAcquire::Item::Start(string const &/*Message*/, unsigned long long const FileSize = Size; } /*}}}*/ +// Acquire::Item::VerifyDone - check if Item was downloaded OK /*{{{*/ +/* Note that hash-verification is 'hardcoded' in acquire-worker and has + * already passed if this method is called. */ +bool pkgAcquire::Item::VerifyDone(std::string const &Message, + pkgAcquire::MethodConfig const * const /*Cnf*/) +{ + std::string const FileName = LookupTag(Message,"Filename"); + if (FileName.empty() == true) + { + Status = StatError; + ErrorText = "Method gave a blank filename"; + return false; + } + + return true; +} + /*}}}*/ // Acquire::Item::Done - Item downloaded OK /*{{{*/ -void pkgAcquire::Item::Done(string const &Message, HashStringList const &Hashes, +void pkgAcquire::Item::Done(string const &/*Message*/, HashStringList const &Hashes, pkgAcquire::MethodConfig const * const /*Cnf*/) { // We just downloaded something.. - UsedMirror = LookupTag(Message,"UsedMirror"); if (FileSize == 0) { unsigned long long const downloadedSize = Hashes.FileSize(); @@ -586,8 +647,8 @@ bool pkgAcquire::Item::RenameOnError(pkgAcquire::Item::RenameOnErrorState const Status = StatError; break; case NotClearsigned: - errtext = _("Does not start with a cleartext signature"); - Status = StatError; + strprintf(errtext, _("Clearsigned file isn't valid, got '%s' (does the network require authentication?)"), "NOSPLIT"); + Status = StatAuthError; break; case MaximumSizeExceeded: // the method is expected to report a good error for this @@ -661,8 +722,8 @@ std::string pkgAcquire::Item::HashSum() const /*{{{*/ /*}}}*/ pkgAcqTransactionItem::pkgAcqTransactionItem(pkgAcquire * const Owner, /*{{{*/ - pkgAcqMetaBase * const TransactionManager, IndexTarget const Target) : - pkgAcquire::Item(Owner), Target(Target), TransactionManager(TransactionManager) + pkgAcqMetaClearSig * const transactionManager, IndexTarget const &target) : + pkgAcquire::Item(Owner), d(NULL), Target(target), TransactionManager(transactionManager) { if (TransactionManager != this) TransactionManager->Add(this); @@ -672,7 +733,7 @@ pkgAcqTransactionItem::~pkgAcqTransactionItem() /*{{{*/ { } /*}}}*/ -HashStringList pkgAcqTransactionItem::GetExpectedHashesFor(std::string const MetaKey) const /*{{{*/ +HashStringList pkgAcqTransactionItem::GetExpectedHashesFor(std::string const &MetaKey) const /*{{{*/ { return GetExpectedHashesFromFor(TransactionManager->MetaIndexParser, MetaKey); } @@ -680,12 +741,11 @@ HashStringList pkgAcqTransactionItem::GetExpectedHashesFor(std::string const Met // AcqMetaBase - Constructor /*{{{*/ pkgAcqMetaBase::pkgAcqMetaBase(pkgAcquire * const Owner, - pkgAcqMetaBase * const TransactionManager, - std::vector const IndexTargets, - IndexTarget const &DataTarget, - indexRecords * const MetaIndexParser) -: pkgAcqTransactionItem(Owner, TransactionManager, DataTarget), - MetaIndexParser(MetaIndexParser), LastMetaIndexParser(NULL), IndexTargets(IndexTargets), + pkgAcqMetaClearSig * const TransactionManager, + std::vector const &IndexTargets, + IndexTarget const &DataTarget) +: pkgAcqTransactionItem(Owner, TransactionManager, DataTarget), d(NULL), + IndexTargets(IndexTargets), AuthPass(false), IMSHit(false) { } @@ -775,7 +835,7 @@ bool pkgAcqMetaBase::CheckStopAuthentication(pkgAcquire::Item * const I, const s _error->Warning(_("An error occurred during the signature " "verification. The repository is not updated " "and the previous index files will be used. " - "GPG error: %s: %s\n"), + "GPG error: %s: %s"), Desc.Description.c_str(), LookupTag(Message,"Message").c_str()); RunScripts("APT::Update::Auth-Failure"); @@ -785,7 +845,7 @@ bool pkgAcqMetaBase::CheckStopAuthentication(pkgAcquire::Item * const I, const s _error->Error(_("GPG error: %s: %s"), Desc.Description.c_str(), LookupTag(Message,"Message").c_str()); - I->Status = StatError; + I->Status = StatAuthError; return true; } else { _error->Warning(_("GPG error: %s: %s"), @@ -808,7 +868,6 @@ string pkgAcqMetaBase::Custom600Headers() const Header += MaximumSize; string const FinalFile = GetFinalFilename(); - struct stat Buf; if (stat(FinalFile.c_str(),&Buf) == 0) Header += "\nLast-Modified: " + TimeRFC1123(Buf.st_mtime); @@ -832,14 +891,7 @@ bool pkgAcqMetaBase::CheckDownloadDone(pkgAcqTransactionItem * const I, const st // We have just finished downloading a Release file (it is not // verified yet) - string const FileName = LookupTag(Message,"Filename"); - if (FileName.empty() == true) - { - I->Status = StatError; - I->ErrorText = "Method gave a blank filename"; - return false; - } - + std::string const FileName = LookupTag(Message,"Filename"); if (FileName != I->DestFile && RealFileExists(I->DestFile) == false) { I->Local = true; @@ -901,26 +953,28 @@ bool pkgAcqMetaBase::CheckAuthDone(string const &Message) /*{{{*/ } if (RealFileExists(FinalInRelease) || RealFileExists(FinalRelease)) { - TransactionManager->LastMetaIndexParser = new indexRecords; - _error->PushToStack(); - if (RealFileExists(FinalInRelease)) - TransactionManager->LastMetaIndexParser->Load(FinalInRelease); - else - TransactionManager->LastMetaIndexParser->Load(FinalRelease); - // its unlikely to happen, but if what we have is bad ignore it - if (_error->PendingError()) + TransactionManager->LastMetaIndexParser = TransactionManager->MetaIndexParser->UnloadedClone(); + if (TransactionManager->LastMetaIndexParser != NULL) { - delete TransactionManager->LastMetaIndexParser; - TransactionManager->LastMetaIndexParser = NULL; + _error->PushToStack(); + if (RealFileExists(FinalInRelease)) + TransactionManager->LastMetaIndexParser->Load(FinalInRelease, NULL); + else + TransactionManager->LastMetaIndexParser->Load(FinalRelease, NULL); + // its unlikely to happen, but if what we have is bad ignore it + if (_error->PendingError()) + { + delete TransactionManager->LastMetaIndexParser; + TransactionManager->LastMetaIndexParser = NULL; + } + _error->RevertToStack(); } - _error->RevertToStack(); } } - if (TransactionManager->MetaIndexParser->Load(DestFile) == false) + if (TransactionManager->MetaIndexParser->Load(DestFile, &ErrorText) == false) { Status = StatAuthError; - ErrorText = TransactionManager->MetaIndexParser->ErrorText; return false; } @@ -945,11 +999,11 @@ void pkgAcqMetaBase::QueueIndexes(bool const verify) /*{{{*/ // at this point the real Items are loaded in the fetcher ExpectedAdditionalItems = 0; - for (std::vector ::const_iterator Target = IndexTargets.begin(); + for (std::vector ::iterator Target = IndexTargets.begin(); Target != IndexTargets.end(); ++Target) { - bool trypdiff = _config->FindB("Acquire::PDiffs", true); + bool trypdiff = Target->OptionBool(IndexTarget::PDIFFS); if (verify == true) { if (TransactionManager->MetaIndexParser->Exists(Target->MetaKey) == false) @@ -963,28 +1017,84 @@ void pkgAcqMetaBase::QueueIndexes(bool const verify) /*{{{*/ return; } - if (RealFileExists(GetFinalFileNameFromURI(Target->URI))) + // autoselect the compression method + std::vector types = VectorizeString(Target->Option(IndexTarget::COMPRESSIONTYPES), ' '); + types.erase(std::remove_if(types.begin(), types.end(), [&](std::string const &t) { + if (t == "uncompressed") + return TransactionManager->MetaIndexParser->Exists(Target->MetaKey) == false; + std::string const MetaKey = Target->MetaKey + "." + t; + return TransactionManager->MetaIndexParser->Exists(MetaKey) == false; + }), types.end()); + if (types.empty() == false) { - if (TransactionManager->LastMetaIndexParser != NULL) + std::ostringstream os; + std::copy(types.begin(), types.end()-1, std::ostream_iterator(os, " ")); + os << *types.rbegin(); + Target->Options["COMPRESSIONTYPES"] = os.str(); + } + else + Target->Options["COMPRESSIONTYPES"].clear(); + + std::string filename = GetFinalFileNameFromURI(Target->URI); + if (RealFileExists(filename) == false) + { + if (Target->KeepCompressed) { + filename = GetKeepCompressedFileName(filename, *Target); + if (RealFileExists(filename) == false) + filename.clear(); + } + else + filename.clear(); + } + + if (filename.empty() == false) + { + // if the Release file is a hit and we have an index it must be the current one + if (TransactionManager->IMSHit == true) + ; + else if (TransactionManager->LastMetaIndexParser != NULL) + { + // see if the file changed since the last Release file + // we use the uncompressed files as we might compress differently compared to the server, + // so the hashes might not match, even if they contain the same data. HashStringList const newFile = GetExpectedHashesFromFor(TransactionManager->MetaIndexParser, Target->MetaKey); HashStringList const oldFile = GetExpectedHashesFromFor(TransactionManager->LastMetaIndexParser, Target->MetaKey); - if (newFile == oldFile) - { - // we have the file already, no point in trying to acquire it again - new NoActionItem(Owner, *Target); - continue; - } + if (newFile != oldFile) + filename.clear(); } + else + filename.clear(); } else trypdiff = false; // no file to patch + if (filename.empty() == false) + { + new NoActionItem(Owner, *Target, filename); + continue; + } + // check if we have patches available trypdiff &= TransactionManager->MetaIndexParser->Exists(Target->MetaKey + ".diff/Index"); } - // if we have no file to patch, no point in trying - trypdiff &= RealFileExists(GetFinalFileNameFromURI(Target->URI)); + else + { + // if we have no file to patch, no point in trying + std::string filename = GetFinalFileNameFromURI(Target->URI); + if (RealFileExists(filename) == false) + { + if (Target->KeepCompressed) + { + filename = GetKeepCompressedFileName(filename, *Target); + if (RealFileExists(filename) == false) + filename.clear(); + } + else + filename.clear(); + } + trypdiff &= (filename.empty() == false); + } // no point in patching from local sources if (trypdiff) @@ -1039,15 +1149,15 @@ bool pkgAcqMetaBase::VerifyVendor(string const &Message) /*{{{*/ Transformed = ""; } - if (_config->FindB("Acquire::Check-Valid-Until", true) == true && - TransactionManager->MetaIndexParser->GetValidUntil() > 0) { + if (TransactionManager->MetaIndexParser->GetValidUntil() > 0) + { time_t const invalid_since = time(NULL) - TransactionManager->MetaIndexParser->GetValidUntil(); if (invalid_since > 0) { std::string errmsg; strprintf(errmsg, // TRANSLATOR: The first %s is the URL of the bad Release file, the second is - // the time since then the file is invalid - formated in the same way as in + // the time since then the file is invalid - formatted in the same way as in // the download progress display (e.g. 7d 3h 42min 1s) _("Release file for %s is expired (invalid since %s). " "Updates for this repository will not be applied."), @@ -1066,14 +1176,16 @@ bool pkgAcqMetaBase::VerifyVendor(string const &Message) /*{{{*/ TransactionManager->IMSHit = true; unlink(DestFile.c_str()); PartialFile = DestFile = GetFinalFilename(); - delete TransactionManager->MetaIndexParser; - TransactionManager->MetaIndexParser = TransactionManager->LastMetaIndexParser; + // load the 'old' file in the 'new' one instead of flipping pointers as + // the new one isn't owned by us, while the old one is so cleanup would be confused. + TransactionManager->MetaIndexParser->swapLoad(TransactionManager->LastMetaIndexParser); + delete TransactionManager->LastMetaIndexParser; TransactionManager->LastMetaIndexParser = NULL; } if (_config->FindB("Debug::pkgAcquire::Auth", false)) { - std::cerr << "Got Codename: " << TransactionManager->MetaIndexParser->GetDist() << std::endl; + std::cerr << "Got Codename: " << TransactionManager->MetaIndexParser->GetCodename() << std::endl; std::cerr << "Expecting Dist: " << TransactionManager->MetaIndexParser->GetExpectedDist() << std::endl; std::cerr << "Transformed Dist: " << Transformed << std::endl; } @@ -1084,30 +1196,33 @@ bool pkgAcqMetaBase::VerifyVendor(string const &Message) /*{{{*/ // Status = StatAuthError; // ErrorText = "Conflicting distribution; expected " // + MetaIndexParser->GetExpectedDist() + " but got " -// + MetaIndexParser->GetDist(); +// + MetaIndexParser->GetCodename(); // return false; if (!Transformed.empty()) { _error->Warning(_("Conflicting distribution: %s (expected %s but got %s)"), Desc.Description.c_str(), Transformed.c_str(), - TransactionManager->MetaIndexParser->GetDist().c_str()); + TransactionManager->MetaIndexParser->GetCodename().c_str()); } } return true; } /*}}}*/ -pkgAcqMetaBase::~pkgAcqMetaBase() {} +pkgAcqMetaBase::~pkgAcqMetaBase() +{ +} pkgAcqMetaClearSig::pkgAcqMetaClearSig(pkgAcquire * const Owner, /*{{{*/ IndexTarget const &ClearsignedTarget, IndexTarget const &DetachedDataTarget, IndexTarget const &DetachedSigTarget, - std::vector const IndexTargets, - indexRecords * const MetaIndexParser) : - pkgAcqMetaIndex(Owner, this, ClearsignedTarget, DetachedSigTarget, IndexTargets, MetaIndexParser), - ClearsignedTarget(ClearsignedTarget), - DetachedDataTarget(DetachedDataTarget), DetachedSigTarget(DetachedSigTarget) + std::vector const &IndexTargets, + metaIndex * const MetaIndexParser) : + pkgAcqMetaIndex(Owner, this, ClearsignedTarget, DetachedSigTarget, IndexTargets), + d(NULL), ClearsignedTarget(ClearsignedTarget), + DetachedDataTarget(DetachedDataTarget), + MetaIndexParser(MetaIndexParser), LastMetaIndexParser(NULL) { // index targets + (worst case:) Release/Release.gpg ExpectedAdditionalItems = IndexTargets.size() + 2; @@ -1116,6 +1231,8 @@ pkgAcqMetaClearSig::pkgAcqMetaClearSig(pkgAcquire * const Owner, /*{{{*/ /*}}}*/ pkgAcqMetaClearSig::~pkgAcqMetaClearSig() /*{{{*/ { + if (LastMetaIndexParser != NULL) + delete LastMetaIndexParser; } /*}}}*/ // pkgAcqMetaClearSig::Custom600Headers - Insert custom request headers /*{{{*/ @@ -1123,9 +1240,23 @@ string pkgAcqMetaClearSig::Custom600Headers() const { string Header = pkgAcqMetaBase::Custom600Headers(); Header += "\nFail-Ignore: true"; + std::string const key = TransactionManager->MetaIndexParser->GetSignedBy(); + if (key.empty() == false) + Header += "\nSigned-By: " + key; + return Header; } /*}}}*/ +bool pkgAcqMetaClearSig::VerifyDone(std::string const &Message, + pkgAcquire::MethodConfig const * const Cnf) +{ + Item::VerifyDone(Message, Cnf); + + if (FileExists(DestFile) && !StartsWithGPGClearTextSignature(DestFile)) + return RenameOnError(NotClearsigned); + + return true; +} // pkgAcqMetaClearSig::Done - We got a file /*{{{*/ void pkgAcqMetaClearSig::Done(std::string const &Message, HashStringList const &Hashes, @@ -1133,17 +1264,6 @@ void pkgAcqMetaClearSig::Done(std::string const &Message, { Item::Done(Message, Hashes, Cnf); - // if we expect a ClearTextSignature (InRelease), ensure that - // this is what we get and if not fail to queue a - // Release/Release.gpg, see #346386 - if (FileExists(DestFile) && !StartsWithGPGClearTextSignature(DestFile)) - { - pkgAcquire::Item::Failed(Message, Cnf); - RenameOnError(NotClearsigned); - TransactionManager->AbortTransaction(); - return; - } - if(AuthPass == false) { if(CheckDownloadDone(this, Message, Hashes) == true) @@ -1174,13 +1294,23 @@ void pkgAcqMetaClearSig::Failed(string const &Message,pkgAcquire::MethodConfig c if (AuthPass == false) { + if (Status == StatAuthError) + { + // if we expected a ClearTextSignature (InRelease) and got a file, + // but it wasn't valid we end up here (see VerifyDone). + // As these is usually called by web-portals we do not try Release/Release.gpg + // as this is gonna fail anyway and instead abort our try (LP#346386) + TransactionManager->AbortTransaction(); + return; + } + // Queue the 'old' InRelease file for removal if we try Release.gpg // as otherwise the file will stay around and gives a false-auth // impression (CVE-2012-0214) TransactionManager->TransactionStageRemoval(this, GetFinalFilename()); Status = StatDone; - new pkgAcqMetaIndex(Owner, TransactionManager, DetachedDataTarget, DetachedSigTarget, IndexTargets, TransactionManager->MetaIndexParser); + new pkgAcqMetaIndex(Owner, TransactionManager, DetachedDataTarget, DetachedSigTarget, IndexTargets); } else { @@ -1212,25 +1342,28 @@ void pkgAcqMetaClearSig::Failed(string const &Message,pkgAcquire::MethodConfig c // open the last Release if we have it if (TransactionManager->IMSHit == false) { - TransactionManager->LastMetaIndexParser = new indexRecords; - _error->PushToStack(); - if (RealFileExists(FinalInRelease)) - TransactionManager->LastMetaIndexParser->Load(FinalInRelease); - else - TransactionManager->LastMetaIndexParser->Load(FinalRelease); - // its unlikely to happen, but if what we have is bad ignore it - if (_error->PendingError()) + TransactionManager->LastMetaIndexParser = TransactionManager->MetaIndexParser->UnloadedClone(); + if (TransactionManager->LastMetaIndexParser != NULL) { - delete TransactionManager->LastMetaIndexParser; - TransactionManager->LastMetaIndexParser = NULL; + _error->PushToStack(); + if (RealFileExists(FinalInRelease)) + TransactionManager->LastMetaIndexParser->Load(FinalInRelease, NULL); + else + TransactionManager->LastMetaIndexParser->Load(FinalRelease, NULL); + // its unlikely to happen, but if what we have is bad ignore it + if (_error->PendingError()) + { + delete TransactionManager->LastMetaIndexParser; + TransactionManager->LastMetaIndexParser = NULL; + } + _error->RevertToStack(); } - _error->RevertToStack(); } } // we parse the indexes here because at this point the user wanted // a repository that may potentially harm him - if (TransactionManager->MetaIndexParser->Load(PartialRelease) == false || VerifyVendor(Message) == false) + if (TransactionManager->MetaIndexParser->Load(PartialRelease, &ErrorText) == false || VerifyVendor(Message) == false) /* expired Release files are still a problem you need extra force for */; else QueueIndexes(true); @@ -1240,12 +1373,11 @@ void pkgAcqMetaClearSig::Failed(string const &Message,pkgAcquire::MethodConfig c /*}}}*/ pkgAcqMetaIndex::pkgAcqMetaIndex(pkgAcquire * const Owner, /*{{{*/ - pkgAcqMetaBase * const TransactionManager, + pkgAcqMetaClearSig * const TransactionManager, IndexTarget const &DataTarget, IndexTarget const &DetachedSigTarget, - vector const IndexTargets, - indexRecords * const MetaIndexParser) : - pkgAcqMetaBase(Owner, TransactionManager, IndexTargets, DataTarget, MetaIndexParser), + vector const &IndexTargets) : + pkgAcqMetaBase(Owner, TransactionManager, IndexTargets, DataTarget), d(NULL), DetachedSigTarget(DetachedSigTarget) { if(_config->FindB("Debug::Acquire::Transaction", false) == true) @@ -1298,8 +1430,6 @@ void pkgAcqMetaIndex::Failed(string const &Message, { // ensure old Release files are removed TransactionManager->TransactionStageRemoval(this, GetFinalFilename()); - delete TransactionManager->MetaIndexParser; - TransactionManager->MetaIndexParser = NULL; // queue without any kind of hashsum support QueueIndexes(false); @@ -1324,10 +1454,10 @@ pkgAcqMetaIndex::~pkgAcqMetaIndex() {} // AcqMetaSig::AcqMetaSig - Constructor /*{{{*/ pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire * const Owner, - pkgAcqMetaBase * const TransactionManager, - IndexTarget const Target, + pkgAcqMetaClearSig * const TransactionManager, + IndexTarget const &Target, pkgAcqMetaIndex * const MetaIndex) : - pkgAcqTransactionItem(Owner, TransactionManager, Target), MetaIndex(MetaIndex) + pkgAcqTransactionItem(Owner, TransactionManager, Target), d(NULL), MetaIndex(MetaIndex) { DestFile = GetPartialFileNameFromURI(Target.URI); @@ -1363,6 +1493,16 @@ pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire * const Owner, /*}}}*/ pkgAcqMetaSig::~pkgAcqMetaSig() /*{{{*/ { +} + /*}}}*/ +// pkgAcqMetaSig::Custom600Headers - Insert custom request headers /*{{{*/ +std::string pkgAcqMetaSig::Custom600Headers() const +{ + std::string Header = pkgAcqTransactionItem::Custom600Headers(); + std::string const key = TransactionManager->MetaIndexParser->GetSignedBy(); + if (key.empty() == false) + Header += "\nSigned-By: " + key; + return Header; } /*}}}*/ // AcqMetaSig::Done - The signature was downloaded/verified /*{{{*/ @@ -1448,25 +1588,28 @@ void pkgAcqMetaSig::Failed(string const &Message,pkgAcquire::MethodConfig const // open the last Release if we have it if (TransactionManager->IMSHit == false) { - TransactionManager->LastMetaIndexParser = new indexRecords; - _error->PushToStack(); - if (RealFileExists(FinalInRelease)) - TransactionManager->LastMetaIndexParser->Load(FinalInRelease); - else - TransactionManager->LastMetaIndexParser->Load(FinalRelease); - // its unlikely to happen, but if what we have is bad ignore it - if (_error->PendingError()) + TransactionManager->LastMetaIndexParser = TransactionManager->MetaIndexParser->UnloadedClone(); + if (TransactionManager->LastMetaIndexParser != NULL) { - delete TransactionManager->LastMetaIndexParser; - TransactionManager->LastMetaIndexParser = NULL; + _error->PushToStack(); + if (RealFileExists(FinalInRelease)) + TransactionManager->LastMetaIndexParser->Load(FinalInRelease, NULL); + else + TransactionManager->LastMetaIndexParser->Load(FinalRelease, NULL); + // its unlikely to happen, but if what we have is bad ignore it + if (_error->PendingError()) + { + delete TransactionManager->LastMetaIndexParser; + TransactionManager->LastMetaIndexParser = NULL; + } + _error->RevertToStack(); } - _error->RevertToStack(); } } // we parse the indexes here because at this point the user wanted // a repository that may potentially harm him - if (TransactionManager->MetaIndexParser->Load(MetaIndex->DestFile) == false || MetaIndex->VerifyVendor(Message) == false) + if (TransactionManager->MetaIndexParser->Load(MetaIndex->DestFile, &ErrorText) == false || MetaIndex->VerifyVendor(Message) == false) /* expired Release files are still a problem you need extra force for */; else MetaIndex->QueueIndexes(true); @@ -1487,9 +1630,9 @@ void pkgAcqMetaSig::Failed(string const &Message,pkgAcquire::MethodConfig const // AcqBaseIndex - Constructor /*{{{*/ pkgAcqBaseIndex::pkgAcqBaseIndex(pkgAcquire * const Owner, - pkgAcqMetaBase * const TransactionManager, - IndexTarget const Target) -: pkgAcqTransactionItem(Owner, TransactionManager, Target) + pkgAcqMetaClearSig * const TransactionManager, + IndexTarget const &Target) +: pkgAcqTransactionItem(Owner, TransactionManager, Target), d(NULL) { } /*}}}*/ @@ -1503,9 +1646,9 @@ pkgAcqBaseIndex::~pkgAcqBaseIndex() {} * the original packages file */ pkgAcqDiffIndex::pkgAcqDiffIndex(pkgAcquire * const Owner, - pkgAcqMetaBase * const TransactionManager, - IndexTarget const Target) - : pkgAcqBaseIndex(Owner, TransactionManager, Target) + pkgAcqMetaClearSig * const TransactionManager, + IndexTarget const &Target) + : pkgAcqBaseIndex(Owner, TransactionManager, Target), d(NULL), diffs(NULL) { Debug = _config->FindB("Debug::pkgAcquire::Diffs",false); @@ -1611,7 +1754,7 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string const &IndexDiffFile) /*{{{*/ LocalHashes = GetExpectedHashesFromFor(TransactionManager->LastMetaIndexParser, Target.MetaKey); if (LocalHashes.usable() == false) { - FileFd fd(CurrentPackagesFile, FileFd::ReadOnly); + FileFd fd(CurrentPackagesFile, FileFd::ReadOnly, FileFd::Auto); Hashes LocalHashesCalc(ServerHashes); LocalHashesCalc.AddFD(fd); LocalHashes = LocalHashesCalc.GetHashStringList(); @@ -1840,7 +1983,7 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string const &IndexDiffFile) /*{{{*/ new pkgAcqIndexDiffs(Owner, TransactionManager, Target, available_patches); else { - std::vector *diffs = new std::vector(available_patches.size()); + diffs = new std::vector(available_patches.size()); for(size_t i = 0; i < available_patches.size(); ++i) (*diffs)[i] = new pkgAcqIndexMergeDiffs(Owner, TransactionManager, Target, @@ -1896,7 +2039,11 @@ void pkgAcqDiffIndex::Done(string const &Message,HashStringList const &Hashes, / return; } /*}}}*/ -pkgAcqDiffIndex::~pkgAcqDiffIndex() {} +pkgAcqDiffIndex::~pkgAcqDiffIndex() +{ + if (diffs != NULL) + delete diffs; +} // AcqIndexDiffs::AcqIndexDiffs - Constructor /*{{{*/ // --------------------------------------------------------------------- @@ -1904,13 +2051,13 @@ pkgAcqDiffIndex::~pkgAcqDiffIndex() {} * for each diff and the index */ pkgAcqIndexDiffs::pkgAcqIndexDiffs(pkgAcquire * const Owner, - pkgAcqMetaBase * const TransactionManager, - IndexTarget const Target, + pkgAcqMetaClearSig * const TransactionManager, + IndexTarget const &Target, vector const &diffs) - : pkgAcqBaseIndex(Owner, TransactionManager, Target), + : pkgAcqBaseIndex(Owner, TransactionManager, Target), d(NULL), available_patches(diffs) { - DestFile = GetPartialFileNameFromURI(Target.URI); + DestFile = GetKeepCompressedFileName(GetPartialFileNameFromURI(Target.URI), Target); Debug = _config->FindB("Debug::pkgAcquire::Diffs",false); @@ -1921,20 +2068,15 @@ pkgAcqIndexDiffs::pkgAcqIndexDiffs(pkgAcquire * const Owner, if(available_patches.empty() == true) { // we are done (yeah!), check hashes against the final file - DestFile = GetFinalFileNameFromURI(Target.URI); + DestFile = GetKeepCompressedFileName(GetFinalFileNameFromURI(Target.URI), Target); Finish(true); } else { - // patching needs to be bootstrapped with the 'old' version - std::string const PartialFile = GetPartialFileNameFromURI(Target.URI); - if (RealFileExists(PartialFile) == false) + if (BootstrapPDiffWith(GetPartialFileNameFromURI(Target.URI), GetFinalFilename(), Target) == false) { - if (symlink(GetFinalFilename().c_str(), PartialFile.c_str()) != 0) - { - Failed("Link creation of " + PartialFile + " to " + GetFinalFilename() + " failed", NULL); - return; - } + Failed("Bootstrapping of " + DestFile + " failed", NULL); + return; } // get the next diff @@ -1948,10 +2090,10 @@ void pkgAcqIndexDiffs::Failed(string const &Message,pkgAcquire::MethodConfig con Item::Failed(Message,Cnf); Status = StatDone; + DestFile = GetKeepCompressedFileName(GetPartialFileNameFromURI(Target.URI), Target); if(Debug) std::clog << "pkgAcqIndexDiffs failed: " << Desc.URI << " with " << Message << std::endl - << "Falling back to normal index file acquire" << std::endl; - DestFile = GetPartialFileNameFromURI(Target.URI); + << "Falling back to normal index file acquire " << std::endl; RenameOnError(PDiffError); std::string const patchname = GetDiffsPatchFileName(DestFile); if (RealFileExists(patchname)) @@ -1972,7 +2114,14 @@ void pkgAcqIndexDiffs::Finish(bool allDone) // the file will be cleaned if(allDone) { - TransactionManager->TransactionStageCopy(this, DestFile, GetFinalFilename()); + std::string Final = GetFinalFilename(); + if (Target.KeepCompressed) + { + std::string const ext = flExtension(DestFile); + if (ext.empty() == false) + Final.append(".").append(ext); + } + TransactionManager->TransactionStageCopy(this, DestFile, Final); // this is for the "real" finish Complete = true; @@ -1982,6 +2131,8 @@ void pkgAcqIndexDiffs::Finish(bool allDone) std::clog << "\n\nallDone: " << DestFile << "\n" << std::endl; return; } + else + DestFile.clear(); if(Debug) std::clog << "Finishing: " << Desc.URI << std::endl; @@ -1994,15 +2145,14 @@ void pkgAcqIndexDiffs::Finish(bool allDone) bool pkgAcqIndexDiffs::QueueNextDiff() /*{{{*/ { // calc sha1 of the just patched file - std::string const FinalFile = GetPartialFileNameFromURI(Target.URI); - + std::string const FinalFile = GetKeepCompressedFileName(GetPartialFileNameFromURI(Target.URI), Target); if(!FileExists(FinalFile)) { Failed("Message: No FinalFile " + FinalFile + " available", NULL); return false; } - FileFd fd(FinalFile, FileFd::ReadOnly); + FileFd fd(FinalFile, FileFd::ReadOnly, FileFd::Extension); Hashes LocalHashesCalc; LocalHashesCalc.AddFD(fd); HashStringList const LocalHashes = LocalHashesCalc.GetHashStringList(); @@ -2046,7 +2196,7 @@ bool pkgAcqIndexDiffs::QueueNextDiff() /*{{{*/ // queue the right diff Desc.URI = Target.URI + ".diff/" + available_patches[0].file + ".gz"; Desc.Description = Description + " " + available_patches[0].file + string(".pdiff"); - DestFile = GetPartialFileNameFromURI(Target.URI + ".diff/" + available_patches[0].file); + DestFile = GetKeepCompressedFileName(GetPartialFileNameFromURI(Target.URI + ".diff/" + available_patches[0].file), Target); if(Debug) std::clog << "pkgAcqIndexDiffs::QueueNextDiff(): " << Desc.URI << std::endl; @@ -2064,7 +2214,7 @@ void pkgAcqIndexDiffs::Done(string const &Message, HashStringList const &Hashes, Item::Done(Message, Hashes, Cnf); - std::string const FinalFile = GetPartialFileNameFromURI(Target.URI); + std::string const FinalFile = GetKeepCompressedFileName(GetPartialFileNameFromURI(Target.URI), Target); std::string const PatchFile = GetDiffsPatchFileName(FinalFile); // success in downloading a diff, enter ApplyDiff state @@ -2127,11 +2277,11 @@ pkgAcqIndexDiffs::~pkgAcqIndexDiffs() {} // AcqIndexMergeDiffs::AcqIndexMergeDiffs - Constructor /*{{{*/ pkgAcqIndexMergeDiffs::pkgAcqIndexMergeDiffs(pkgAcquire * const Owner, - pkgAcqMetaBase * const TransactionManager, - IndexTarget const Target, + pkgAcqMetaClearSig * const TransactionManager, + IndexTarget const &Target, DiffInfo const &patch, std::vector const * const allPatches) - : pkgAcqBaseIndex(Owner, TransactionManager, Target), + : pkgAcqBaseIndex(Owner, TransactionManager, Target), d(NULL), patch(patch), allPatches(allPatches), State(StateFetchDiff) { Debug = _config->FindB("Debug::pkgAcquire::Diffs",false); @@ -2143,7 +2293,7 @@ pkgAcqIndexMergeDiffs::pkgAcqIndexMergeDiffs(pkgAcquire * const Owner, Desc.URI = Target.URI + ".diff/" + patch.file + ".gz"; Desc.Description = Description + " " + patch.file + string(".pdiff"); - DestFile = GetPartialFileNameFromURI(Target.URI + ".diff/" + patch.file); + DestFile = GetKeepCompressedFileName(GetPartialFileNameFromURI(Target.URI + ".diff/" + patch.file), Target); if(Debug) std::clog << "pkgAcqIndexMergeDiffs: " << Desc.URI << std::endl; @@ -2170,12 +2320,13 @@ void pkgAcqIndexMergeDiffs::Failed(string const &Message,pkgAcquire::MethodConfi State = StateErrorDiff; if (Debug) std::clog << "Falling back to normal index file acquire" << std::endl; - DestFile = GetPartialFileNameFromURI(Target.URI); + DestFile = GetKeepCompressedFileName(GetPartialFileNameFromURI(Target.URI), Target); RenameOnError(PDiffError); std::string const patchname = GetMergeDiffsPatchFileName(DestFile, patch.file); if (RealFileExists(patchname)) rename(patchname.c_str(), std::string(patchname + ".FAILED").c_str()); new pkgAcqIndex(Owner, TransactionManager, Target); + DestFile.clear(); } /*}}}*/ void pkgAcqIndexMergeDiffs::Done(string const &Message, HashStringList const &Hashes, /*{{{*/ @@ -2186,7 +2337,8 @@ void pkgAcqIndexMergeDiffs::Done(string const &Message, HashStringList const &Ha Item::Done(Message, Hashes, Cnf); - string const FinalFile = GetPartialFileNameFromURI(Target.URI); + std::string const UncompressedFinalFile = GetPartialFileNameFromURI(Target.URI); + std::string const FinalFile = GetKeepCompressedFileName(GetPartialFileNameFromURI(Target.URI), Target); if (State == StateFetchDiff) { Rename(DestFile, GetMergeDiffsPatchFileName(FinalFile, patch.file)); @@ -2205,10 +2357,9 @@ void pkgAcqIndexMergeDiffs::Done(string const &Message, HashStringList const &Ha // this is the last completed diff, so we are ready to apply now State = StateApplyDiff; - // patching needs to be bootstrapped with the 'old' version - if (symlink(GetFinalFilename().c_str(), FinalFile.c_str()) != 0) + if (BootstrapPDiffWith(UncompressedFinalFile, GetFinalFilename(), Target) == false) { - Failed("Link creation of " + FinalFile + " to " + GetFinalFilename() + " failed", NULL); + Failed("Bootstrapping of " + DestFile + " failed", NULL); return; } @@ -2225,7 +2376,7 @@ void pkgAcqIndexMergeDiffs::Done(string const &Message, HashStringList const &Ha else if (State == StateApplyDiff) { // move the result into place - std::string const Final = GetFinalFilename(); + std::string const Final = GetKeepCompressedFileName(GetFinalFilename(), Target); if(Debug) std::clog << "Queue patched file in place: " << std::endl << DestFile << " -> " << Final << std::endl; @@ -2237,7 +2388,7 @@ void pkgAcqIndexMergeDiffs::Done(string const &Message, HashStringList const &Ha for (std::vector::const_iterator I = allPatches->begin(); I != allPatches->end(); ++I) { - std::string const PartialFile = GetPartialFileNameFromURI(Target.URI); + std::string const PartialFile = GetKeepCompressedFileName(GetPartialFileNameFromURI(Target.URI), Target); std::string const patch = GetMergeDiffsPatchFileName(PartialFile, (*I)->patch.file); unlink(patch.c_str()); } @@ -2272,12 +2423,11 @@ pkgAcqIndexMergeDiffs::~pkgAcqIndexMergeDiffs() {} // AcqIndex::AcqIndex - Constructor /*{{{*/ pkgAcqIndex::pkgAcqIndex(pkgAcquire * const Owner, - pkgAcqMetaBase * const TransactionManager, - IndexTarget const Target) - : pkgAcqBaseIndex(Owner, TransactionManager, Target) + pkgAcqMetaClearSig * const TransactionManager, + IndexTarget const &Target) + : pkgAcqBaseIndex(Owner, TransactionManager, Target), d(NULL), Stage(STAGE_DOWNLOAD), + CompressionExtensions(Target.Option(IndexTarget::COMPRESSIONTYPES)) { - // autoselect the compression method - AutoSelectCompression(); Init(Target.URI, Target.Description, Target.ShortDesc); if(_config->FindB("Debug::Acquire::Transaction", false) == true) @@ -2285,31 +2435,6 @@ pkgAcqIndex::pkgAcqIndex(pkgAcquire * const Owner, << TransactionManager << std::endl; } /*}}}*/ -// AcqIndex::AutoSelectCompression - Select compression /*{{{*/ -void pkgAcqIndex::AutoSelectCompression() -{ - std::vector types = APT::Configuration::getCompressionTypes(); - CompressionExtensions = ""; - if (TransactionManager->MetaIndexParser != NULL && TransactionManager->MetaIndexParser->Exists(Target.MetaKey)) - { - for (std::vector::const_iterator t = types.begin(); - t != types.end(); ++t) - { - std::string CompressedMetaKey = string(Target.MetaKey).append(".").append(*t); - if (*t == "uncompressed" || - TransactionManager->MetaIndexParser->Exists(CompressedMetaKey) == true) - CompressionExtensions.append(*t).append(" "); - } - } - else - { - for (std::vector::const_iterator t = types.begin(); t != types.end(); ++t) - CompressionExtensions.append(*t).append(" "); - } - if (CompressionExtensions.empty() == false) - CompressionExtensions.erase(CompressionExtensions.end()-1); -} - /*}}}*/ // AcqIndex::Init - defered Constructor /*{{{*/ void pkgAcqIndex::Init(string const &URI, string const &URIDesc, string const &ShortDesc) @@ -2427,7 +2552,7 @@ void pkgAcqIndex::ReverifyAfterIMS() { // update destfile to *not* include the compression extension when doing // a reverify (as its uncompressed on disk already) - DestFile = GetCompressedFileName(Target.URI, GetPartialFileNameFromURI(Target.URI), CurrentCompressionExtension); + DestFile = GetCompressedFileName(Target, GetPartialFileNameFromURI(Target.URI), CurrentCompressionExtension); // copy FinalFile into partial/ so that we check the hash again string FinalFile = GetFinalFilename(); @@ -2467,7 +2592,7 @@ void pkgAcqIndex::StageDownloadDone(string const &Message, HashStringList const Complete = true; // Handle the unzipd case - string FileName = LookupTag(Message,"Alt-Filename"); + std::string FileName = LookupTag(Message,"Alt-Filename"); if (FileName.empty() == false) { Stage = STAGE_DECOMPRESS_AND_VERIFY; @@ -2478,13 +2603,7 @@ void pkgAcqIndex::StageDownloadDone(string const &Message, HashStringList const SetActiveSubprocess("copy"); return; } - FileName = LookupTag(Message,"Filename"); - if (FileName.empty() == true) - { - Status = StatError; - ErrorText = "Method gave a blank filename"; - } // Methods like e.g. "file:" will give us a (compressed) FileName that is // not the "DestFile" we set, in this case we uncompress from the local file @@ -2503,8 +2622,8 @@ void pkgAcqIndex::StageDownloadDone(string const &Message, HashStringList const return; } - // If we have compressed indexes enabled, queue for hash verification - if (_config->FindB("Acquire::GzipIndexes",false)) + // If we want compressed indexes, just copy in place for hash verification + if (Target.KeepCompressed == true) { DestFile = GetPartialFileNameFromURI(Target.URI + '.' + CurrentCompressionExtension); EraseFileName = ""; @@ -2555,7 +2674,7 @@ pkgAcqIndex::~pkgAcqIndex() {} pkgAcqArchive::pkgAcqArchive(pkgAcquire * const Owner,pkgSourceList * const Sources, pkgRecords * const Recs,pkgCache::VerIterator const &Version, string &StoreFilename) : - Item(Owner), LocalSource(false), Version(Version), Sources(Sources), Recs(Recs), + Item(Owner), d(NULL), LocalSource(false), Version(Version), Sources(Sources), Recs(Recs), StoreFilename(StoreFilename), Vf(Version.FileList()), Trusted(false) { @@ -2758,15 +2877,7 @@ void pkgAcqArchive::Done(string const &Message, HashStringList const &Hashes, Item::Done(Message, Hashes, Cfg); // Grab the output filename - string FileName = LookupTag(Message,"Filename"); - if (FileName.empty() == true) - { - Status = StatError; - ErrorText = "Method gave a blank filename"; - return; - } - - // Reference filename + std::string const FileName = LookupTag(Message,"Filename"); if (DestFile != FileName && RealFileExists(DestFile) == false) { StoreFilename = DestFile = FileName; @@ -2888,7 +2999,8 @@ void pkgAcqChangelog::Init(std::string const &DestDir, std::string const &DestFi if (DestDir.empty()) { - std::string const systemTemp = GetTempDir(); + std::string const SandboxUser = _config->Find("APT::Sandbox::User"); + std::string const systemTemp = GetTempDir(SandboxUser); char tmpname[100]; snprintf(tmpname, sizeof(tmpname), "%s/apt-changelog-XXXXXX", systemTemp.c_str()); if (NULL == mkdtemp(tmpname)) @@ -2898,6 +3010,9 @@ void pkgAcqChangelog::Init(std::string const &DestDir, std::string const &DestFi return; } DestFile = TemporaryDirectory = tmpname; + + ChangeOwnerAndPermissionOfFile("Item::QueueURI", DestFile.c_str(), + SandboxUser.c_str(), "root", 0700); } else DestFile = DestDir; @@ -3048,7 +3163,7 @@ pkgAcqFile::pkgAcqFile(pkgAcquire * const Owner,string const &URI, HashStringLis unsigned long long const Size,string const &Dsc,string const &ShortDesc, const string &DestDir, const string &DestFilename, bool const IsIndexFile) : - Item(Owner), IsIndexFile(IsIndexFile), ExpectedHashes(Hashes) + Item(Owner), d(NULL), IsIndexFile(IsIndexFile), ExpectedHashes(Hashes) { Retries = _config->FindI("Acquire::Retries",0); @@ -3088,14 +3203,7 @@ void pkgAcqFile::Done(string const &Message,HashStringList const &CalcHashes, { Item::Done(Message,CalcHashes,Cnf); - string FileName = LookupTag(Message,"Filename"); - if (FileName.empty() == true) - { - Status = StatError; - ErrorText = "Method gave a blank filename"; - return; - } - + std::string const FileName = LookupTag(Message,"Filename"); Complete = true; // The files timestamp matches