/*}}}*/
// Acquire::Item::Item - Constructor /*{{{*/
+#if __GNUC__ >= 4
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
pkgAcquire::Item::Item(pkgAcquire *Owner,
HashStringList const &ExpectedHashes,
- unsigned long TransactionID)
+ pkgAcqMetaBase *TransactionManager)
: Owner(Owner), FileSize(0), PartialSize(0), Mode(0), ID(0), Complete(false),
- Local(false), QueueCounter(0), TransactionID(TransactionID),
+ Local(false), QueueCounter(0), TransactionManager(TransactionManager),
ExpectedAdditionalItems(0), ExpectedHashes(ExpectedHashes)
{
Owner->Add(this);
Status = StatIdle;
+ if(TransactionManager != NULL)
+ TransactionManager->Add(this);
}
+#if __GNUC__ >= 4
+ #pragma GCC diagnostic pop
+#endif
/*}}}*/
// Acquire::Item::~Item - Destructor /*{{{*/
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
/* This helper function is used by a lot of item methods as their final
step */
-void pkgAcquire::Item::Rename(string From,string To)
+bool pkgAcquire::Item::Rename(string From,string To)
{
if (rename(From.c_str(),To.c_str()) != 0)
{
snprintf(S,sizeof(S),_("rename failed, %s (%s -> %s)."),strerror(errno),
From.c_str(),To.c_str());
Status = StatError;
- ErrorText = S;
+ ErrorText += S;
+ return false;
}
+ return true;
}
/*}}}*/
bool pkgAcquire::Item::RenameOnError(pkgAcquire::Item::RenameOnErrorState const error)/*{{{*/
Status = StatError;
// do not report as usually its not the mirrors fault, but Portal/Proxy
break;
+ case SignatureError:
+ ErrorText = _("Signature error");
+ Status = StatError;
+ break;
+ case NotClearsigned:
+ ErrorText = _("Does not start with a cleartext signature");
+ Status = StatError;
+ break;
}
return false;
}
}
}
/*}}}*/
-// AcqSubIndex::AcqSubIndex - Constructor /*{{{*/
-// ---------------------------------------------------------------------
-/* Get a sub-index file based on checksums from a 'master' file and
- possibly query additional files */
-pkgAcqSubIndex::pkgAcqSubIndex(pkgAcquire *Owner,
- unsigned long TransactionID,
- string const &URI,
- string const &URIDesc, string const &ShortDesc,
- HashStringList const &ExpectedHashes)
- : Item(Owner, ExpectedHashes, TransactionID)
-{
- /* XXX: Beware: Currently this class does nothing (of value) anymore ! */
- Debug = _config->FindB("Debug::pkgAcquire::SubIndex",false);
-
- DestFile = _config->FindDir("Dir::State::lists") + "partial/";
- DestFile += URItoFileName(URI);
-
- Desc.URI = URI;
- Desc.Description = URIDesc;
- Desc.Owner = this;
- Desc.ShortDesc = ShortDesc;
-
- QueueURI(Desc);
-
- if(Debug)
- std::clog << "pkgAcqSubIndex: " << Desc.URI << std::endl;
-}
- /*}}}*/
-// AcqSubIndex::Custom600Headers - Insert custom request headers /*{{{*/
-// ---------------------------------------------------------------------
-/* The only header we use is the last-modified header. */
-string pkgAcqSubIndex::Custom600Headers() const
-{
- string Final = _config->FindDir("Dir::State::lists");
- Final += URItoFileName(Desc.URI);
-
- struct stat Buf;
- if (stat(Final.c_str(),&Buf) != 0)
- return "\nIndex-File: true\nFail-Ignore: true\n";
- return "\nIndex-File: true\nFail-Ignore: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
-}
- /*}}}*/
-void pkgAcqSubIndex::Failed(string Message,pkgAcquire::MethodConfig * /*Cnf*/)/*{{{*/
-{
- if(Debug)
- std::clog << "pkgAcqSubIndex failed: " << Desc.URI << " with " << Message << std::endl;
-
- Complete = false;
- Status = StatDone;
- Dequeue();
-
- // No good Index is provided
-}
- /*}}}*/
-void pkgAcqSubIndex::Done(string Message,unsigned long long Size,HashStringList const &Hashes, /*{{{*/
- pkgAcquire::MethodConfig *Cnf)
-{
- if(Debug)
- std::clog << "pkgAcqSubIndex::Done(): " << Desc.URI << std::endl;
-
- string FileName = LookupTag(Message,"Filename");
- if (FileName.empty() == true)
- {
- Status = StatError;
- ErrorText = "Method gave a blank filename";
- return;
- }
-
- if (FileName != DestFile)
- {
- Local = true;
- Desc.URI = "copy:" + FileName;
- QueueURI(Desc);
- return;
- }
-
- Item::Done(Message, Size, Hashes, Cnf);
-
- string FinalFile = _config->FindDir("Dir::State::lists")+URItoFileName(Desc.URI);
-
- /* Downloaded invalid transindex => Error (LP: #346386) (Closes: #627642) */
- indexRecords SubIndexParser;
- if (FileExists(DestFile) == true && !SubIndexParser.Load(DestFile)) {
- Status = StatError;
- ErrorText = SubIndexParser.ErrorText;
- return;
- }
-
- // success in downloading the index
- // rename the index
- if(Debug)
- std::clog << "Renaming: " << DestFile << " -> " << FinalFile << std::endl;
- Rename(DestFile,FinalFile);
- chmod(FinalFile.c_str(),0644);
- DestFile = FinalFile;
-
- if(ParseIndex(DestFile) == false)
- return Failed("", NULL);
-
- Complete = true;
- Status = StatDone;
- Dequeue();
- return;
-}
- /*}}}*/
-bool pkgAcqSubIndex::ParseIndex(string const &IndexFile) /*{{{*/
-{
- indexRecords SubIndexParser;
- if (FileExists(IndexFile) == false || SubIndexParser.Load(IndexFile) == false)
- return false;
- // so something with the downloaded index
- return true;
-}
- /*}}}*/
// AcqDiffIndex::AcqDiffIndex - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* Get the DiffIndex file first and see if there are patches available
* the original packages file
*/
pkgAcqDiffIndex::pkgAcqDiffIndex(pkgAcquire *Owner,
- unsigned long TransactionID,
+ pkgAcqMetaBase *TransactionManager,
IndexTarget const * const Target,
HashStringList const &ExpectedHashes,
indexRecords *MetaIndexParser)
- : pkgAcqBaseIndex(Owner, TransactionID, Target, ExpectedHashes,
- MetaIndexParser)
+ : pkgAcqBaseIndex(Owner, TransactionManager, Target, ExpectedHashes,
+ MetaIndexParser), PackagesFileReadyInPartial(false)
{
Debug = _config->FindB("Debug::pkgAcquire::Diffs",false);
// we have the same sha1 as the server so we are done here
if(Debug)
std::clog << "Package file is up-to-date" << std::endl;
+ // ensure we have no leftovers from previous runs
+ std::string Partial = _config->FindDir("Dir::State::lists");
+ Partial += "partial/" + URItoFileName(RealURI);
+ unlink(Partial.c_str());
// 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, TransactionID, Target,
+ new pkgAcqIndexDiffs(Owner, TransactionManager, Target,
ExpectedHashes, MetaIndexParser,
ServerSha1, available_patches);
return true;
// we have something, queue the next diff
if(found)
{
+ // FIXME: make this use the method
+ PackagesFileReadyInPartial = true;
+ std::string Partial = _config->FindDir("Dir::State::lists");
+ Partial += "partial/" + URItoFileName(RealURI);
+
+ FileFd From(CurrentPackagesFile, FileFd::ReadOnly);
+ FileFd To(Partial, FileFd::WriteEmpty);
+ if(CopyFile(From, To) == false)
+ return _error->Errno("CopyFile", "failed to copy");
+
+ if(Debug)
+ std::cerr << "Done copying " << CurrentPackagesFile
+ << " -> " << Partial
+ << std::endl;
+
// queue the diffs
string::size_type const last_space = Description.rfind(" ");
if(last_space != string::npos)
if (pdiff_merge == false)
{
- new pkgAcqIndexDiffs(Owner, TransactionID, Target, ExpectedHashes,
+ new pkgAcqIndexDiffs(Owner, TransactionManager, Target, ExpectedHashes,
MetaIndexParser,
ServerSha1, available_patches);
}
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,
- TransactionID,
+ TransactionManager,
Target,
ExpectedHashes,
MetaIndexParser,
diffs);
}
- Complete = false;
- Status = StatDone;
- Dequeue();
- return true;
+ Complete = false;
+ Status = StatDone;
+ Dequeue();
+ return true;
}
}
std::clog << "pkgAcqDiffIndex failed: " << Desc.URI << " with " << Message << std::endl
<< "Falling back to normal index file acquire" << std::endl;
- new pkgAcqIndex(Owner, TransactionID, Target, ExpectedHashes, MetaIndexParser);
+ new pkgAcqIndex(Owner, TransactionManager, Target, ExpectedHashes, MetaIndexParser);
Complete = false;
Status = StatDone;
* for each diff and the index
*/
pkgAcqIndexDiffs::pkgAcqIndexDiffs(pkgAcquire *Owner,
- unsigned long TransactionID,
+ pkgAcqMetaBase *TransactionManager,
struct IndexTarget const * const Target,
HashStringList const &ExpectedHashes,
indexRecords *MetaIndexParser,
string ServerSha1,
vector<DiffInfo> diffs)
- : pkgAcqBaseIndex(Owner, TransactionID, Target, ExpectedHashes, MetaIndexParser),
+ : pkgAcqBaseIndex(Owner, TransactionManager, Target, ExpectedHashes, MetaIndexParser),
available_patches(diffs), ServerSha1(ServerSha1)
{
if(available_patches.empty() == true)
{
- // we are done (yeah!)
+ // we are done (yeah!), check hashes against the final file
+ DestFile = _config->FindDir("Dir::State::lists");
+ DestFile += URItoFileName(Target->URI);
Finish(true);
}
else
if(Debug)
std::clog << "pkgAcqIndexDiffs failed: " << Desc.URI << " with " << Message << std::endl
<< "Falling back to normal index file acquire" << std::endl;
- new pkgAcqIndex(Owner, TransactionID, Target, ExpectedHashes, MetaIndexParser);
+ new pkgAcqIndex(Owner, TransactionManager, Target, ExpectedHashes, MetaIndexParser);
Finish();
}
/*}}}*/
// the file will be cleaned
if(allDone)
{
- DestFile = _config->FindDir("Dir::State::lists");
- DestFile += URItoFileName(RealURI);
-
- // FIXME: we want the rred stuff to use the real transactional update
- // this is just a workaround
- PartialFile = DestFile;
-
if(HashSums().usable() && !HashSums().VerifyFile(DestFile))
{
RenameOnError(HashSumMismatch);
return;
}
+ // queue for copy
+ PartialFile = _config->FindDir("Dir::State::lists")+"partial/"+URItoFileName(RealURI);
+
+ DestFile = _config->FindDir("Dir::State::lists");
+ DestFile += URItoFileName(RealURI);
+
+ // this happens if we have a up-to-date indexfile
+ if(!FileExists(PartialFile))
+ PartialFile = DestFile;
+
// this is for the "real" finish
Complete = true;
Status = StatDone;
/*}}}*/
bool pkgAcqIndexDiffs::QueueNextDiff() /*{{{*/
{
-
// calc sha1 of the just patched file
string FinalFile = _config->FindDir("Dir::State::lists");
- FinalFile += URItoFileName(RealURI);
+ FinalFile += "partial/" + URItoFileName(RealURI);
+
+ if(!FileExists(FinalFile))
+ {
+ Failed("No FinalFile " + FinalFile + " available", NULL);
+ return false;
+ }
FileFd fd(FinalFile, FileFd::ReadOnly);
SHA1Summation SHA1;
std::clog << "QueueNextDiff: "
<< FinalFile << " (" << local_sha1 << ")"<<std::endl;
+
// final file reached before all patches are applied
if(local_sha1 == ServerSha1)
{
// error checking and falling back if no patch was found
if(available_patches.empty() == true)
{
- Failed("", NULL);
+ Failed("No patches available", NULL);
return false;
}
Item::Done(Message, Size, Hashes, Cnf);
string FinalFile;
- FinalFile = _config->FindDir("Dir::State::lists")+URItoFileName(RealURI);
+ FinalFile = _config->FindDir("Dir::State::lists")+"partial/"+URItoFileName(RealURI);
// success in downloading a diff, enter ApplyDiff state
if(State == StateFetchDiff)
Local = true;
Desc.URI = "rred:" + FinalFile;
QueueURI(Desc);
+ ActiveSubprocess = "rred";
+#if __GNUC__ >= 4
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
Mode = "rred";
+#if __GNUC__ >= 4
+ #pragma GCC diagnostic pop
+#endif
return;
}
// see if there is more to download
if(available_patches.empty() == false) {
- new pkgAcqIndexDiffs(Owner, TransactionID, Target,
+ new pkgAcqIndexDiffs(Owner, TransactionManager, Target,
ExpectedHashes, MetaIndexParser,
ServerSha1, available_patches);
return Finish();
} else
+ // update
+ DestFile = FinalFile;
return Finish(true);
}
}
/*}}}*/
// AcqIndexMergeDiffs::AcqIndexMergeDiffs - Constructor /*{{{*/
pkgAcqIndexMergeDiffs::pkgAcqIndexMergeDiffs(pkgAcquire *Owner,
- unsigned long TransactionID,
+ pkgAcqMetaBase *TransactionManager,
struct IndexTarget const * const Target,
HashStringList const &ExpectedHashes,
indexRecords *MetaIndexParser,
DiffInfo const &patch,
std::vector<pkgAcqIndexMergeDiffs*> const * const allPatches)
- : pkgAcqBaseIndex(Owner, TransactionID, Target, ExpectedHashes, MetaIndexParser),
+ : pkgAcqBaseIndex(Owner, TransactionManager, 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, TransactionID, Target, ExpectedHashes, MetaIndexParser);
+ new pkgAcqIndex(Owner, TransactionManager, Target, ExpectedHashes, MetaIndexParser);
}
/*}}}*/
void pkgAcqIndexMergeDiffs::Done(string Message,unsigned long long Size,HashStringList const &Hashes, /*{{{*/
Item::Done(Message,Size,Hashes,Cnf);
- string const FinalFile = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
+ string const FinalFile = _config->FindDir("Dir::State::lists") + "partial/" + URItoFileName(RealURI);
if (State == StateFetchDiff)
{
Local = true;
Desc.URI = "rred:" + FinalFile;
QueueURI(Desc);
+ ActiveSubprocess = "rred";
+#if __GNUC__ >= 4
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
Mode = "rred";
+#if __GNUC__ >= 4
+ #pragma GCC diagnostic pop
+#endif
return;
}
// success in download/apply all diffs, clean up
return;
}
+
+ std::string FinalFile = _config->FindDir("Dir::State::lists");
+ FinalFile += URItoFileName(RealURI);
+
// move the result into place
if(Debug)
- std::clog << "Moving patched file in place: " << std::endl
+ std::clog << "Queue patched file in place: " << std::endl
<< DestFile << " -> " << FinalFile << std::endl;
- Rename(DestFile, FinalFile);
- chmod(FinalFile.c_str(), 0644);
- // otherwise lists cleanup will eat the file
+ // queue for copy by the transaction manager
+ PartialFile = DestFile;
DestFile = FinalFile;
- // FIXME: make the merged rred code really transactional
- PartialFile = FinalFile;
// ensure the ed's are gone regardless of list-cleanup
for (std::vector<pkgAcqIndexMergeDiffs *>::const_iterator I = allPatches->begin();
I != allPatches->end(); ++I)
{
- std::string patch = FinalFile + ".ed." + (*I)->patch.file + ".gz";
+ std::string PartialFile = _config->FindDir("Dir::State::lists");
+ PartialFile += "partial/" + URItoFileName(RealURI);
+ std::string patch = PartialFile + ".ed." + (*I)->patch.file + ".gz";
+ std::cerr << patch << std::endl;
unlink(patch.c_str());
}
instantiated to fetch the revision file */
pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,
string URI,string URIDesc,string ShortDesc,
- HashStringList const &ExpectedHash, string comprExt)
+ HashStringList const &ExpectedHash)
: pkgAcqBaseIndex(Owner, 0, NULL, ExpectedHash, NULL), RealURI(URI)
{
AutoSelectCompression();
Init(URI, URIDesc, ShortDesc);
if(_config->FindB("Debug::Acquire::Transaction", false) == true)
- std::clog << "New pkgIndex with TransactionID "
- << TransactionID << std::endl;
+ std::clog << "New pkgIndex with TransactionManager "
+ << TransactionManager << std::endl;
}
/*}}}*/
// AcqIndex::AcqIndex - Constructor /*{{{*/
// ---------------------------------------------------------------------
pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,
- unsigned long TransactionID,
+ pkgAcqMetaBase *TransactionManager,
IndexTarget const *Target,
HashStringList const &ExpectedHash,
indexRecords *MetaIndexParser)
- : pkgAcqBaseIndex(Owner, TransactionID, Target, ExpectedHash,
+ : pkgAcqBaseIndex(Owner, TransactionManager, Target, ExpectedHash,
MetaIndexParser), RealURI(Target->URI)
{
// autoselect the compression method
Init(Target->URI, Target->Description, Target->ShortDesc);
if(_config->FindB("Debug::Acquire::Transaction", false) == true)
- std::clog << "New pkgIndex with TransactionID "
- << TransactionID << std::endl;
+ std::clog << "New pkgIndex with TransactionManager "
+ << TransactionManager << std::endl;
}
/*}}}*/
// AcqIndex::AutoSelectCompression - Select compression /*{{{*/
CompressionExtension.erase(CompressionExtension.end()-1);
}
// AcqIndex::Init - defered Constructor /*{{{*/
-void pkgAcqIndex::Init(string const &URI, string const &URIDesc, string const &ShortDesc) {
+// ---------------------------------------------------------------------
+void pkgAcqIndex::Init(string const &URI, string const &URIDesc,
+ string const &ShortDesc)
+{
Decompression = false;
Erase = false;
else
{
Desc.URI = URI + '.' + comprExt;
+ DestFile = DestFile + '.' + comprExt;
if(Target)
MetaKey = string(Target->MetaKey) + '.' + comprExt;
}
/* The only header we use is the last-modified header. */
string pkgAcqIndex::Custom600Headers() const
{
- string Final = _config->FindDir("Dir::State::lists");
- Final += URItoFileName(RealURI);
- if (_config->FindB("Acquire::GzipIndexes",false))
- Final += ".gz";
+ string Final = GetFinalFilename();
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);
Item::Failed(Message,Cnf);
/// cancel the entire transaction
- Owner->AbortTransaction(TransactionID);
+ TransactionManager->AbortTransaction();
}
/*}}}*/
// pkgAcqIndex::GetFinalFilename - Return the full final file path /*{{{*/
// ---------------------------------------------------------------------
/* */
-std::string pkgAcqIndex::GetFinalFilename(std::string const &URI,
- std::string const &compExt)
+std::string pkgAcqIndex::GetFinalFilename() const
{
+ std::string const compExt = CompressionExtension.substr(0, CompressionExtension.find(' '));
std::string FinalFile = _config->FindDir("Dir::State::lists");
- FinalFile += URItoFileName(URI);
- if (_config->FindB("Acquire::GzipIndexes",false) && compExt == "gz")
- FinalFile += ".gz";
+ FinalFile += URItoFileName(RealURI);
+ if (_config->FindB("Acquire::GzipIndexes",false) == true)
+ FinalFile += '.' + compExt;
return FinalFile;
}
/*}}}*/
// AcqIndex::ReverifyAfterIMS - Reverify index after an ims-hit /*{{{*/
// ---------------------------------------------------------------------
/* */
-void pkgAcqIndex::ReverifyAfterIMS(std::string const &FileName)
+void pkgAcqIndex::ReverifyAfterIMS()
{
std::string const compExt = CompressionExtension.substr(0, CompressionExtension.find(' '));
- if (_config->FindB("Acquire::GzipIndexes",false) && compExt == "gz")
- DestFile += ".gz";
+
+ // update destfile to *not* include the compression extension when doing
+ // a reverify (as its uncompressed on disk already)
+ DestFile = _config->FindDir("Dir::State::lists") + "partial/";
+ DestFile += URItoFileName(RealURI);
+
+ // adjust DestFile if its compressed on disk
+ if (_config->FindB("Acquire::GzipIndexes",false) == true)
+ DestFile += '.' + compExt;
// copy FinalFile into partial/ so that we check the hash again
- string FinalFile = GetFinalFilename(RealURI, compExt);
+ string FinalFile = GetFinalFilename();
Decompression = true;
Desc.URI = "copy:" + FinalFile;
QueueURI(Desc);
to the uncompressed version of the file. If this is so the file
is copied into the partial directory. In all other cases the file
is decompressed with a compressed uri. */
-void pkgAcqIndex::Done(string Message,unsigned long long Size,HashStringList const &Hashes,
+void pkgAcqIndex::Done(string Message, unsigned long long Size,
+ HashStringList const &Hashes,
pkgAcquire::MethodConfig *Cfg)
{
Item::Done(Message,Size,Hashes,Cfg);
{
if (ExpectedHashes.usable() && ExpectedHashes != Hashes)
{
+ Desc.URI = RealURI;
RenameOnError(HashSumMismatch);
printHashSumComparision(RealURI, ExpectedHashes, Hashes);
Failed(Message, Cfg);
// FIXME: can we void the "Erase" bool here as its very non-local?
std::string CompressedFile = _config->FindDir("Dir::State::lists") + "partial/";
CompressedFile += URItoFileName(RealURI);
+
// Remove the compressed version.
if (Erase == true)
unlink(CompressedFile.c_str());
// Done, queue for rename on transaction finished
PartialFile = DestFile;
- DestFile = GetFinalFilename(RealURI, compExt);
+ DestFile = GetFinalFilename();
return;
}
string FileName = LookupTag(Message,"Alt-Filename");
if (FileName.empty() == false)
{
- // The files timestamp matches
- if (StringToBool(LookupTag(Message,"Alt-IMS-Hit"),false) == true)
- {
- ReverifyAfterIMS(FileName);
- return;
- }
Decompression = true;
Local = true;
DestFile += ".decomp";
Desc.URI = "copy:" + FileName;
QueueURI(Desc);
+ ActiveSubprocess = "copy";
+#if __GNUC__ >= 4
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
Mode = "copy";
+#if __GNUC__ >= 4
+ #pragma GCC diagnostic pop
+#endif
return;
}
ErrorText = "Method gave a blank filename";
}
- // The files timestamp matches
- if (StringToBool(LookupTag(Message,"IMS-Hit"),false) == true)
- {
- ReverifyAfterIMS(FileName);
- return;
- }
-
if (FileName == DestFile)
Erase = true;
else
Local = true;
-
+
+ // do not reverify cdrom sources as apt-cdrom may rewrite the Packages
+ // file when its doing the indexcopy
+ if (RealURI.substr(0,6) == "cdrom:" &&
+ StringToBool(LookupTag(Message,"IMS-Hit"),false) == true)
+ return;
+
+ // The files timestamp matches, reverify by copy into partial/
+ if (StringToBool(LookupTag(Message,"IMS-Hit"),false) == true)
+ {
+ Erase = false;
+ ReverifyAfterIMS();
+#if 0 // ???
+ // set destfile to the final destfile
+ if(_config->FindB("Acquire::GzipIndexes",false) == false)
+ {
+ DestFile = _config->FindDir("Dir::State::lists") + "partial/";
+ DestFile += URItoFileName(RealURI);
+ }
+
+ ReverifyAfterIMS(FileName);
+#endif
+ return;
+ }
string decompProg;
- // If we enable compressed indexes and already have gzip, keep it
- if (_config->FindB("Acquire::GzipIndexes",false) && compExt == "gz" && !Local) {
- // Done, queue for rename on transaction finished
- PartialFile = DestFile;
- DestFile = GetFinalFilename(RealURI, compExt);
+ // If we enable compressed indexes, queue for hash verification
+ if (_config->FindB("Acquire::GzipIndexes",false))
+ {
+ DestFile = _config->FindDir("Dir::State::lists");
+ DestFile += URItoFileName(RealURI) + '.' + compExt;
+
+ Decompression = true;
+ Desc.URI = "copy:" + FileName;
+ QueueURI(Desc);
+
return;
}
Desc.URI = decompProg + ":" + FileName;
QueueURI(Desc);
- // FIXME: this points to a c++ string that goes out of scope
- Mode = decompProg.c_str();
+ ActiveSubprocess = decompProg;
+#if __GNUC__ >= 4
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
+ Mode = ActiveSubprocess.c_str();
+#if __GNUC__ >= 4
+ #pragma GCC diagnostic pop
+#endif
}
/*}}}*/
// AcqIndexTrans::pkgAcqIndexTrans - Constructor /*{{{*/
/* The Translation file is added to the queue */
pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcquire *Owner,
string URI,string URIDesc,string ShortDesc)
- : pkgAcqIndex(Owner, URI, URIDesc, ShortDesc, HashStringList(), "")
+ : pkgAcqIndex(Owner, URI, URIDesc, ShortDesc, HashStringList())
{
}
/*}}}*/
pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcquire *Owner,
- unsigned long TransactionID,
+ pkgAcqMetaBase *TransactionManager,
IndexTarget const * const Target,
HashStringList const &ExpectedHashes,
indexRecords *MetaIndexParser)
- : pkgAcqIndex(Owner, TransactionID, Target, ExpectedHashes, MetaIndexParser)
+ : pkgAcqIndex(Owner, TransactionManager, Target, ExpectedHashes, MetaIndexParser)
{
// load the filesize
indexRecords::checkSum *Record = MetaIndexParser->Lookup(string(Target->MetaKey));
// ---------------------------------------------------------------------
string pkgAcqIndexTrans::Custom600Headers() const
{
- string Final = _config->FindDir("Dir::State::lists");
- Final += URItoFileName(RealURI);
+ string Final = GetFinalFilename();
struct stat Buf;
if (stat(Final.c_str(),&Buf) != 0)
}
/*}}}*/
-pkgAcqMetaSigBase::pkgAcqMetaSigBase(pkgAcquire *Owner,
- HashStringList const &ExpectedHashes,
- unsigned long TransactionID)
- : Item(Owner, ExpectedHashes, TransactionID)
+void pkgAcqMetaBase::Add(Item *I)
+{
+ Transaction.push_back(I);
+}
+
+void pkgAcqMetaBase::AbortTransaction()
{
+ if(_config->FindB("Debug::Acquire::Transaction", false) == true)
+ std::clog << "AbortTransaction: " << TransactionManager << std::endl;
+
+ // ensure the toplevel is in error state too
+ for (std::vector<Item*>::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 pkgAcqMetaBase::TransactionHasError()
+{
+ for (pkgAcquire::ItemIterator I = Transaction.begin();
+ I != Transaction.end(); ++I)
+ if((*I)->Status != pkgAcquire::Item::StatDone &&
+ (*I)->Status != pkgAcquire::Item::StatIdle)
+ return true;
+
+ return false;
}
+// Acquire::CommitTransaction - Commit a transaction /*{{{*/
+void pkgAcqMetaBase::CommitTransaction()
+{
+ if(_config->FindB("Debug::Acquire::Transaction", false) == true)
+ std::clog << "CommitTransaction: " << this << std::endl;
+
+ // move new files into place *and* remove files that are not
+ // part of the transaction but are still on disk
+ for (std::vector<Item*>::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 << " "
+ << (*I)->DescURI()
+ << 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
+ << " "
+ << (*I)->DescURI()
+ << std::endl;
+ unlink((*I)->DestFile.c_str());
+ }
+ // mark that this transaction is finished
+ (*I)->TransactionManager = 0;
+ }
+}
+
/*{{{*/
-bool pkgAcqMetaSigBase::GenerateAuthWarning(const std::string &RealURI,
- const std::string &Message)
+bool pkgAcqMetaBase::GenerateAuthWarning(const std::string &RealURI,
+ const std::string &Message)
{
string Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire *Owner, /*{{{*/
- unsigned long TransactionID,
+ pkgAcqMetaBase *TransactionManager,
string URI,string URIDesc,string ShortDesc,
string MetaIndexFile,
const vector<IndexTarget*>* IndexTargets,
indexRecords* MetaIndexParser) :
- pkgAcqMetaSigBase(Owner, HashStringList(), TransactionID), RealURI(URI),
- MetaIndexParser(MetaIndexParser), MetaIndexFile(MetaIndexFile),
- IndexTargets(IndexTargets), AuthPass(false), IMSHit(false)
+ pkgAcqMetaBase(Owner, IndexTargets, MetaIndexParser,
+ HashStringList(), TransactionManager),
+ RealURI(URI), MetaIndexFile(MetaIndexFile), URIDesc(URIDesc),
+ ShortDesc(ShortDesc), AuthPass(false), IMSHit(false)
{
DestFile = _config->FindDir("Dir::State::lists") + "partial/";
DestFile += URItoFileName(URI);
// partial download anyway
unlink(DestFile.c_str());
- // set the TransactionID
+ // set the TransactionManager
if(_config->FindB("Debug::Acquire::Transaction", false) == true)
- std::clog << "New pkgAcqMetaSig with TransactionID "
- << TransactionID << std::endl;
+ std::clog << "New pkgAcqMetaSig with TransactionManager "
+ << TransactionManager << std::endl;
// Create the item
Desc.Description = URIDesc;
DestFile += URItoFileName(RealURI);
}
- Complete = true;
+ // we parse the MetaIndexFile here because at this point we can
+ // trust the data
+ if(AuthPass == true)
+ {
+ // load indexes and queue further downloads
+ MetaIndexParser->Load(MetaIndexFile);
+ QueueIndexes(true);
+ }
+ Complete = true;
}
/*}}}*/
void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf)/*{{{*/
{
string Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
+
+ // FIXME: meh, this is not really elegant
+ string InReleaseURI = RealURI.replace(RealURI.rfind("Release.gpg"), 12,
+ "InRelease");
+ string FinalInRelease = _config->FindDir("Dir::State::lists") + URItoFileName(InReleaseURI);
+
+ if(RealFileExists(Final) || RealFileExists(FinalInRelease))
+ {
+ _error->Error("The repository '%s' is no longer signed.",
+ URIDesc.c_str());
+ Rename(MetaIndexFile, MetaIndexFile+".FAILED");
+ Status = pkgAcquire::Item::StatError;
+ TransactionManager->AbortTransaction();
+ return;
+ }
// this ensures that any file in the lists/ dir is removed by the
// transaction
return;
}
+ // only allow going further if the users explicitely wants it
+ if(_config->FindB("APT::Get::AllowUnauthenticated", false) == true)
+ {
+ // we parse the indexes here because at this point the user wanted
+ // a repository that may potentially harm him
+ MetaIndexParser->Load(MetaIndexFile);
+ QueueIndexes(true);
+ }
+ else
+ {
+ _error->Warning("Use --allow-unauthenticated to force the update");
+ }
+
// FIXME: this is used often (e.g. in pkgAcqIndexTrans) so refactor
if (Cnf->LocalOnly == true ||
StringToBool(LookupTag(Message,"Transient-Failure"),false) == false)
}
/*}}}*/
pkgAcqMetaIndex::pkgAcqMetaIndex(pkgAcquire *Owner, /*{{{*/
- unsigned long TransactionID,
+ pkgAcqMetaBase *TransactionManager,
string URI,string URIDesc,string ShortDesc,
string MetaIndexSigURI,string MetaIndexSigURIDesc, string MetaIndexSigShortDesc,
const vector<IndexTarget*>* IndexTargets,
indexRecords* MetaIndexParser) :
- pkgAcqMetaSigBase(Owner, HashStringList(), TransactionID), RealURI(URI), IndexTargets(IndexTargets),
- MetaIndexParser(MetaIndexParser), AuthPass(false), IMSHit(false),
+ pkgAcqMetaBase(Owner, IndexTargets, MetaIndexParser, HashStringList(),
+ TransactionManager),
+ RealURI(URI), URIDesc(URIDesc), ShortDesc(ShortDesc),
+ AuthPass(false), IMSHit(false),
MetaIndexSigURI(MetaIndexSigURI), MetaIndexSigURIDesc(MetaIndexSigURIDesc),
MetaIndexSigShortDesc(MetaIndexSigShortDesc)
{
- if(TransactionID == 0)
- this->TransactionID = (unsigned long)this;
+ if(TransactionManager == NULL)
+ {
+ this->TransactionManager = this;
+ this->TransactionManager->Add(this);
+ }
if(_config->FindB("Debug::Acquire::Transaction", false) == true)
- std::clog << "New pkgAcqMetaIndex with TransactionID "
- << TransactionID << std::endl;
+ std::clog << "New pkgAcqMetaIndex with TransactionManager "
+ << this->TransactionManager << std::endl;
+
Init(URIDesc, ShortDesc);
}
// Still more retrieving to do
return;
- if (SigFile == "")
- {
- // load indexes, the signature will downloaded afterwards
- MetaIndexParser->Load(DestFile);
- QueueIndexes(true);
- }
- else
+ if (SigFile != "")
{
// There was a signature file, so pass it to gpgv for
// verification
AuthPass = true;
Desc.URI = "gpgv:" + SigFile;
QueueURI(Desc);
- Mode = "gpgv";
+ ActiveSubprocess = "gpgv";
+#if __GNUC__ >= 4
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
+ Mode = "gpgv";
+#if __GNUC__ >= 4
+ #pragma GCC diagnostic pop
+#endif
return;
}
}
// queue a signature
if(SigFile != DestFile)
- new pkgAcqMetaSig(Owner, TransactionID,
+ new pkgAcqMetaSig(Owner, TransactionManager,
MetaIndexSigURI, MetaIndexSigURIDesc,
MetaIndexSigShortDesc, DestFile, IndexTargets,
MetaIndexParser);
std::cerr << "Signature verification succeeded: "
<< DestFile << std::endl;
- // Download further indexes with verification
+// we ensure this by other means
+#if 0
+ // do not trust any previously unverified content that we may have
+ string LastGoodSigFile = _config->FindDir("Dir::State::lists").append("partial/").append(URItoFileName(RealURI));
+ if (DestFile != SigFile)
+ LastGoodSigFile.append(".gpg");
+ LastGoodSigFile.append(".reverify");
+ if(IMSHit == false && RealFileExists(LastGoodSigFile) == false)
+ {
+ for (vector <struct IndexTarget*>::const_iterator Target = IndexTargets->begin();
+ Target != IndexTargets->end();
+ ++Target)
+ {
+ // remove old indexes
+ std::string index = _config->FindDir("Dir::State::lists") +
+ URItoFileName((*Target)->URI);
+ unlink(index.c_str());
+ // and also old gzipindexes
+ std::vector<std::string> types = APT::Configuration::getCompressionTypes();
+ for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
+ {
+ index += '.' + (*t);
+ unlink(index.c_str());
+ }
+ }
+ }
+#endif
+
+ // Download further indexes with verification
+ //
+ // it would be really nice if we could simply do
+ // if (IMSHit == false) QueueIndexes(true)
+ // and skip the download if the Release file has not changed
+ // - but right now the list cleaner will needs to be tricked
+ // to not delete all our packages/source indexes in this case
QueueIndexes(true);
#if 0
#endif
}
/*}}}*/
-void pkgAcqMetaIndex::QueueIndexes(bool verify) /*{{{*/
+void pkgAcqMetaBase::QueueIndexes(bool verify) /*{{{*/
{
bool transInRelease = false;
{
if ((*Target)->IsOptional() == true)
{
- if ((*Target)->IsSubIndex() == true)
- new pkgAcqSubIndex(Owner, TransactionID,
- (*Target)->URI, (*Target)->Description,
- (*Target)->ShortDesc, ExpectedIndexHashes);
- else if (transInRelease == false || Record != NULL || compressedAvailable == true)
+ if (transInRelease == false || Record != NULL || compressedAvailable == true)
{
if (_config->FindB("Acquire::PDiffs",true) == true && transInRelease == true &&
MetaIndexParser->Exists((*Target)->MetaKey + ".diff/Index") == true)
- new pkgAcqDiffIndex(Owner, TransactionID, *Target, ExpectedIndexHashes, MetaIndexParser);
+ new pkgAcqDiffIndex(Owner, TransactionManager, *Target, ExpectedIndexHashes, MetaIndexParser);
else
- new pkgAcqIndexTrans(Owner, TransactionID, *Target, ExpectedIndexHashes, MetaIndexParser);
+ new pkgAcqIndexTrans(Owner, TransactionManager, *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, TransactionID, *Target, ExpectedIndexHashes, MetaIndexParser);
+ new pkgAcqDiffIndex(Owner, TransactionManager, *Target, ExpectedIndexHashes, MetaIndexParser);
else
- new pkgAcqIndex(Owner, TransactionID, *Target, ExpectedIndexHashes, MetaIndexParser);
+ new pkgAcqIndex(Owner, TransactionManager, *Target, ExpectedIndexHashes, MetaIndexParser);
}
}
/*}}}*/
/* Always move the meta index, even if gpgv failed. This ensures
* that PackageFile objects are correctly filled in */
- if (FileExists(DestFile)) {
+ if (FileExists(DestFile))
+ {
string FinalFile = _config->FindDir("Dir::State::lists");
FinalFile += URItoFileName(RealURI);
/* InRelease files become Release files, otherwise
DestFile = FinalFile;
}
+ _error->Warning(_("The data from '%s' is not signed. Packages "
+ "from that repository can not be authenticated."),
+ URIDesc.c_str());
+
// No Release file was present, or verification failed, so fall
// back to queueing Packages files without verification
- QueueIndexes(false);
+ // only allow going further if the users explicitely wants it
+ if(_config->FindB("APT::Get::AllowUnauthenticated", false) == true)
+ {
+ QueueIndexes(false);
+ } else {
+ // warn if the repository is unsinged
+ _error->Warning("Use --allow-unauthenticated to force the update");
+ }
}
/*}}}*/
{
if(_config->FindB("Debug::Acquire::Transaction", false) == true)
std::clog << "Finished: " << DestFile <<std::endl;
- if(Owner->TransactionHasError(TransactionID) == false &&
- TransactionID > 0)
- Owner->CommitTransaction(TransactionID);
+ if(TransactionManager != NULL &&
+ TransactionManager->TransactionHasError() == false)
+ TransactionManager->CommitTransaction();
}
string const &MetaSigURI, string const &MetaSigURIDesc, string const &MetaSigShortDesc,
const vector<IndexTarget*>* IndexTargets,
indexRecords* MetaIndexParser) :
- pkgAcqMetaIndex(Owner, (unsigned long)this, URI, URIDesc, ShortDesc, MetaSigURI, MetaSigURIDesc,MetaSigShortDesc, IndexTargets, MetaIndexParser),
+ pkgAcqMetaIndex(Owner, NULL, URI, URIDesc, ShortDesc, MetaSigURI, MetaSigURIDesc,MetaSigShortDesc, IndexTargets, MetaIndexParser),
MetaIndexURI(MetaIndexURI), MetaIndexURIDesc(MetaIndexURIDesc), MetaIndexShortDesc(MetaIndexShortDesc),
MetaSigURI(MetaSigURI), MetaSigURIDesc(MetaSigURIDesc), MetaSigShortDesc(MetaSigShortDesc)
{
if (FileExists(DestFile) && !StartsWithGPGClearTextSignature(DestFile))
{
pkgAcquire::Item::Failed(Message, Cnf);
- ErrorText = _("Does not start with a cleartext signature");
+ RenameOnError(NotClearsigned);
+ TransactionManager->AbortTransaction();
return;
}
pkgAcqMetaIndex::Done(Message, Size, Hashes, Cnf);
PartialFile = "";
DestFile = FinalFile;
- new pkgAcqMetaIndex(Owner, TransactionID,
+ new pkgAcqMetaIndex(Owner, TransactionManager,
MetaIndexURI, MetaIndexURIDesc, MetaIndexShortDesc,
MetaSigURI, MetaSigURIDesc, MetaSigShortDesc,
IndexTargets, MetaIndexParser);