summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/acquire-item.cc403
-rw-r--r--apt-pkg/acquire-item.h100
-rw-r--r--apt-pkg/algorithms.cc23
-rw-r--r--apt-pkg/aptconfiguration.cc59
-rw-r--r--apt-pkg/cacheiterators.h18
-rw-r--r--apt-pkg/cdrom.cc6
-rw-r--r--apt-pkg/contrib/error.cc31
-rw-r--r--apt-pkg/contrib/fileutl.cc48
-rw-r--r--apt-pkg/contrib/fileutl.h2
-rw-r--r--apt-pkg/contrib/progress.cc2
-rw-r--r--apt-pkg/contrib/strutl.cc17
-rw-r--r--apt-pkg/contrib/strutl.h1
-rw-r--r--apt-pkg/contrib/weakptr.h2
-rw-r--r--apt-pkg/deb/debindexfile.cc8
-rw-r--r--apt-pkg/deb/deblistparser.cc114
-rw-r--r--apt-pkg/deb/debmetaindex.cc109
-rw-r--r--apt-pkg/deb/debmetaindex.h2
-rw-r--r--apt-pkg/deb/dpkgpm.cc12
-rw-r--r--apt-pkg/depcache.cc184
-rw-r--r--apt-pkg/depcache.h19
-rw-r--r--apt-pkg/indexcopy.cc3
-rw-r--r--apt-pkg/indexrecords.cc17
-rw-r--r--apt-pkg/init.cc11
-rw-r--r--apt-pkg/pkgcachegen.cc18
-rw-r--r--apt-pkg/policy.cc4
-rw-r--r--apt-pkg/sourcelist.cc6
-rw-r--r--apt-pkg/tagfile.cc10
-rw-r--r--apt-pkg/tagfile.h2
-rw-r--r--apt-pkg/vendorlist.cc4
29 files changed, 947 insertions, 288 deletions
diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc
index 2c4ce91a0..d4df31e85 100644
--- a/apt-pkg/acquire-item.cc
+++ b/apt-pkg/acquire-item.cc
@@ -184,6 +184,151 @@ void pkgAcquire::Item::ReportMirrorFailure(string FailCode)
}
}
/*}}}*/
+// AcqSubIndex::AcqSubIndex - Constructor /*{{{*/
+// ---------------------------------------------------------------------
+/* Get the Index file first and see if there are languages available
+ * If so, create a pkgAcqIndexTrans for the found language(s).
+ */
+pkgAcqSubIndex::pkgAcqSubIndex(pkgAcquire *Owner, string const &URI,
+ string const &URIDesc, string const &ShortDesc,
+ HashString const &ExpectedHash)
+ : Item(Owner), ExpectedHash(ExpectedHash)
+{
+ 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()
+{
+ 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";
+ return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
+}
+ /*}}}*/
+void pkgAcqSubIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*{{{*/
+{
+ if(Debug)
+ std::clog << "pkgAcqSubIndex failed: " << Desc.URI << std::endl;
+
+ Complete = false;
+ Status = StatDone;
+ Dequeue();
+
+ // No good Index is provided, so try guessing
+ std::vector<std::string> langs = APT::Configuration::getLanguages(true);
+ for (std::vector<std::string>::const_iterator l = langs.begin();
+ l != langs.end(); ++l)
+ {
+ if (*l == "none") continue;
+ string const file = "Translation-" + *l;
+ new pkgAcqIndexTrans(Owner, Desc.URI.substr(0, Desc.URI.rfind('/')+1).append(file),
+ Desc.Description.erase(Desc.Description.rfind(' ')+1).append(file),
+ file);
+ }
+}
+ /*}}}*/
+void pkgAcqSubIndex::Done(string Message,unsigned long Size,string Md5Hash, /*{{{*/
+ 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,Md5Hash,Cnf);
+
+ string FinalFile = _config->FindDir("Dir::State::lists")+URItoFileName(Desc.URI);
+
+ // sucess 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;
+
+ std::vector<std::string> lang = APT::Configuration::getLanguages(true);
+ for (std::vector<std::string>::const_iterator l = lang.begin();
+ l != lang.end(); ++l)
+ {
+ if (*l == "none")
+ continue;
+
+ string file = "Translation-" + *l;
+ indexRecords::checkSum const *Record = SubIndexParser.Lookup(file);
+ HashString expected;
+ if (Record == NULL)
+ {
+ // FIXME: the Index file provided by debian currently only includes bz2 records
+ Record = SubIndexParser.Lookup(file + ".bz2");
+ if (Record == NULL)
+ continue;
+ }
+ else
+ {
+ expected = Record->Hash;
+ if (expected.empty() == true)
+ continue;
+ }
+
+ IndexTarget target;
+ target.Description = Desc.Description.erase(Desc.Description.rfind(' ')+1).append(file);
+ target.MetaKey = file;
+ target.ShortDesc = file;
+ target.URI = Desc.URI.substr(0, Desc.URI.rfind('/')+1).append(file);
+ new pkgAcqIndexTrans(Owner, &target, expected, &SubIndexParser);
+ }
+ return true;
+}
+ /*}}}*/
// AcqDiffIndex::AcqDiffIndex - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* Get the DiffIndex file first and see if there are patches availabe
@@ -570,24 +715,7 @@ void pkgAcqIndexDiffs::Done(string Message,unsigned long Size,string Md5Hash, /*
FinalFile = _config->FindDir("Dir::State::lists")+URItoFileName(RealURI);
// sucess in downloading a diff, enter ApplyDiff state
- if(State == StateFetchDiff)
- {
-
- if(Debug)
- std::clog << "Sending to gzip method: " << FinalFile << std::endl;
-
- string FileName = LookupTag(Message,"Filename");
- State = StateUnzipDiff;
- Local = true;
- Desc.URI = "gzip:" + FileName;
- DestFile += ".decomp";
- QueueURI(Desc);
- Mode = "gzip";
- return;
- }
-
- // sucess in downloading a diff, enter ApplyDiff state
- if(State == StateUnzipDiff)
+ if(State == StateFetchDiff)
{
// rred excepts the patch as $FinalFile.ed
@@ -639,29 +767,61 @@ pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,
HashString ExpectedHash, string comprExt)
: Item(Owner), RealURI(URI), ExpectedHash(ExpectedHash)
{
+ if(comprExt.empty() == true)
+ {
+ // autoselect the compression method
+ std::vector<std::string> types = APT::Configuration::getCompressionTypes();
+ for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
+ comprExt.append(*t).append(" ");
+ if (comprExt.empty() == false)
+ comprExt.erase(comprExt.end()-1);
+ }
+ CompressionExtension = comprExt;
+
+ Init(URI, URIDesc, ShortDesc);
+}
+pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner, IndexTarget const *Target,
+ HashString const &ExpectedHash, indexRecords const *MetaIndexParser)
+ : Item(Owner), RealURI(Target->URI), ExpectedHash(ExpectedHash)
+{
+ // autoselect the compression method
+ std::vector<std::string> types = APT::Configuration::getCompressionTypes();
+ CompressionExtension = "";
+ if (ExpectedHash.empty() == false)
+ {
+ for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
+ if (*t == "uncompressed" || MetaIndexParser->Exists(string(Target->MetaKey).append(".").append(*t)) == true)
+ CompressionExtension.append(*t).append(" ");
+ }
+ else
+ {
+ for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
+ CompressionExtension.append(*t).append(" ");
+ }
+ if (CompressionExtension.empty() == false)
+ CompressionExtension.erase(CompressionExtension.end()-1);
+
+ Init(Target->URI, Target->Description, Target->ShortDesc);
+}
+ /*}}}*/
+// AcqIndex::Init - defered Constructor /*{{{*/
+void pkgAcqIndex::Init(string const &URI, string const &URIDesc, string const &ShortDesc) {
Decompression = false;
Erase = false;
DestFile = _config->FindDir("Dir::State::lists") + "partial/";
DestFile += URItoFileName(URI);
- if(comprExt.empty())
- {
- // autoselect the compression method
- std::vector<std::string> types = APT::Configuration::getCompressionTypes();
- if (types.empty() == true)
- comprExt = "plain";
- else
- comprExt = "." + types[0];
- }
- CompressionExtension = ((comprExt == "plain" || comprExt == ".") ? "" : comprExt);
-
- Desc.URI = URI + CompressionExtension;
+ std::string const comprExt = CompressionExtension.substr(0, CompressionExtension.find(' '));
+ if (comprExt == "uncompressed")
+ Desc.URI = URI;
+ else
+ Desc.URI = URI + '.' + comprExt;
Desc.Description = URIDesc;
Desc.Owner = this;
Desc.ShortDesc = ShortDesc;
-
+
QueueURI(Desc);
}
/*}}}*/
@@ -683,37 +843,18 @@ string pkgAcqIndex::Custom600Headers()
/*}}}*/
void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*{{{*/
{
- std::vector<std::string> types = APT::Configuration::getCompressionTypes();
-
- for (std::vector<std::string>::const_iterator t = types.begin();
- t != types.end(); t++)
+ size_t const nextExt = CompressionExtension.find(' ');
+ if (nextExt != std::string::npos)
{
- // jump over all already tried compression types
- const unsigned int nameLen = Desc.URI.size() - (*t).size();
- if(Desc.URI.substr(nameLen) != *t)
- continue;
-
- // we want to try it with the next extension (and make sure to
- // not skip over the end)
- t++;
- if (t == types.end())
- break;
-
- // queue new download
- Desc.URI = Desc.URI.substr(0, nameLen) + *t;
- new pkgAcqIndex(Owner, RealURI, Desc.Description, Desc.ShortDesc,
- ExpectedHash, string(".").append(*t));
-
- Status = StatDone;
- Complete = false;
- Dequeue();
+ CompressionExtension = CompressionExtension.substr(nextExt+1);
+ Init(RealURI, Desc.Description, Desc.ShortDesc);
return;
}
// on decompression failure, remove bad versions in partial/
- if(Decompression && Erase) {
+ if (Decompression && Erase) {
string s = _config->FindDir("Dir::State::lists") + "partial/";
- s += URItoFileName(RealURI);
+ s.append(URItoFileName(RealURI));
unlink(s.c_str());
}
@@ -790,8 +931,8 @@ void pkgAcqIndex::Done(string Message,unsigned long Size,string Hash,
Status = StatError;
ErrorText = "Method gave a blank filename";
}
-
- string compExt = flExtension(flNotDir(URI(Desc.URI).Path));
+
+ std::string const compExt = CompressionExtension.substr(0, CompressionExtension.find(' '));
// The files timestamp matches
if (StringToBool(LookupTag(Message,"IMS-Hit"),false) == true) {
@@ -824,12 +965,7 @@ void pkgAcqIndex::Done(string Message,unsigned long Size,string Hash,
// get the binary name for your used compression type
decompProg = _config->Find(string("Acquire::CompressionTypes::").append(compExt),"");
if(decompProg.empty() == false);
- // flExtensions returns the full name if no extension is found
- // this is why we have this complicated compare operation here
- // FIMXE: add a new flJustExtension() that return "" if no
- // extension is found and use that above so that it can
- // be tested against ""
- else if(compExt == flNotDir(URI(Desc.URI).Path))
+ else if(compExt == "uncompressed")
decompProg = "copy";
else {
_error->Error("Unsupported extension: %s", compExt.c_str());
@@ -851,6 +987,11 @@ pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcquire *Owner,
: pkgAcqIndex(Owner, URI, URIDesc, ShortDesc, HashString(), "")
{
}
+pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcquire *Owner, IndexTarget const *Target,
+ HashString const &ExpectedHash, indexRecords const *MetaIndexParser)
+ : pkgAcqIndex(Owner, Target, ExpectedHash, MetaIndexParser)
+{
+}
/*}}}*/
// AcqIndexTrans::Custom600Headers - Insert custom request headers /*{{{*/
// ---------------------------------------------------------------------
@@ -870,6 +1011,15 @@ string pkgAcqIndexTrans::Custom600Headers()
/* */
void pkgAcqIndexTrans::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
{
+ size_t const nextExt = CompressionExtension.find(' ');
+ if (nextExt != std::string::npos)
+ {
+ CompressionExtension = CompressionExtension.substr(nextExt+1);
+ Init(RealURI, Desc.Description, Desc.ShortDesc);
+ Status = StatIdle;
+ return;
+ }
+
if (Cnf->LocalOnly == true ||
StringToBool(LookupTag(Message,"Transient-Failure"),false) == false)
{
@@ -879,7 +1029,7 @@ void pkgAcqIndexTrans::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
Dequeue();
return;
}
-
+
Item::Failed(Message,Cnf);
}
/*}}}*/
@@ -1094,6 +1244,8 @@ void pkgAcqMetaIndex::Done(string Message,unsigned long Size,string Hash, /*{{{*
{
string FinalFile = _config->FindDir("Dir::State::lists");
FinalFile += URItoFileName(RealURI);
+ if (SigFile == DestFile)
+ SigFile = FinalFile;
Rename(DestFile,FinalFile);
chmod(FinalFile.c_str(),0644);
DestFile = FinalFile;
@@ -1127,6 +1279,8 @@ void pkgAcqMetaIndex::RetrievalDone(string Message) /*{{{*/
{
string FinalFile = _config->FindDir("Dir::State::lists");
FinalFile += URItoFileName(RealURI);
+ if (SigFile == DestFile)
+ SigFile = FinalFile;
DestFile = FinalFile;
}
Complete = true;
@@ -1158,6 +1312,10 @@ void pkgAcqMetaIndex::AuthDone(string Message) /*{{{*/
// Download further indexes with verification
QueueIndexes(true);
+ // is it a clearsigned MetaIndex file?
+ if (DestFile == SigFile)
+ return;
+
// Done, move signature file into position
string VerifiedSigFile = _config->FindDir("Dir::State::lists") +
URItoFileName(RealURI) + ".gpg";
@@ -1174,27 +1332,41 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify) /*{{{*/
HashString ExpectedIndexHash;
if (verify)
{
- const indexRecords::checkSum *Record = MetaIndexParser->Lookup((*Target)->MetaKey);
- if (!Record)
- {
- Status = StatAuthError;
- ErrorText = "Unable to find expected entry "
- + (*Target)->MetaKey + " in Meta-index file (malformed Release file?)";
- return;
- }
- ExpectedIndexHash = Record->Hash;
- if (_config->FindB("Debug::pkgAcquire::Auth", false))
- {
- std::cerr << "Queueing: " << (*Target)->URI << std::endl;
- std::cerr << "Expected Hash: " << ExpectedIndexHash.toStr() << std::endl;
- }
- if (ExpectedIndexHash.empty())
- {
- Status = StatAuthError;
- ErrorText = "Unable to find hash sum for "
- + (*Target)->MetaKey + " in Meta-index file";
- return;
- }
+ const indexRecords::checkSum *Record = MetaIndexParser->Lookup((*Target)->MetaKey);
+ if (Record == NULL)
+ {
+ if ((*Target)->IsOptional() == false)
+ {
+ Status = StatAuthError;
+ strprintf(ErrorText, _("Unable to find expected entry '%s' in Release file (Wrong sources.list entry or malformed file)"), (*Target)->MetaKey.c_str());
+ return;
+ }
+ }
+ else
+ {
+ ExpectedIndexHash = Record->Hash;
+ if (_config->FindB("Debug::pkgAcquire::Auth", false))
+ {
+ std::cerr << "Queueing: " << (*Target)->URI << std::endl;
+ std::cerr << "Expected Hash: " << ExpectedIndexHash.toStr() << std::endl;
+ }
+ if (ExpectedIndexHash.empty() == true && (*Target)->IsOptional() == false)
+ {
+ Status = StatAuthError;
+ strprintf(ErrorText, _("Unable to find hash sum for '%s' in Release file"), (*Target)->MetaKey.c_str());
+ return;
+ }
+ }
+ }
+
+ if ((*Target)->IsOptional() == true)
+ {
+ if ((*Target)->IsSubIndex() == true)
+ new pkgAcqSubIndex(Owner, (*Target)->URI, (*Target)->Description,
+ (*Target)->ShortDesc, ExpectedIndexHash);
+ else
+ new pkgAcqIndexTrans(Owner, *Target, ExpectedIndexHash, MetaIndexParser);
+ continue;
}
/* Queue Packages file (either diff or full packages files, depending
@@ -1206,8 +1378,7 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify) /*{{{*/
new pkgAcqDiffIndex(Owner, (*Target)->URI, (*Target)->Description,
(*Target)->ShortDesc, ExpectedIndexHash);
else
- new pkgAcqIndex(Owner, (*Target)->URI, (*Target)->Description,
- (*Target)->ShortDesc, ExpectedIndexHash);
+ new pkgAcqIndex(Owner, *Target, ExpectedIndexHash, MetaIndexParser);
}
}
/*}}}*/
@@ -1317,13 +1488,20 @@ void pkgAcqMetaIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
if (AuthPass == true)
{
// gpgv method failed, if we have a good signature
- string LastGoodSigFile = _config->FindDir("Dir::State::lists") +
- "partial/" + URItoFileName(RealURI) + ".gpg.reverify";
+ string LastGoodSigFile = _config->FindDir("Dir::State::lists");
+ if (DestFile == SigFile)
+ LastGoodSigFile.append(URItoFileName(RealURI));
+ else
+ LastGoodSigFile.append("partial/").append(URItoFileName(RealURI)).append(".gpg.reverify");
+
if(FileExists(LastGoodSigFile))
{
- string VerifiedSigFile = _config->FindDir("Dir::State::lists") +
- URItoFileName(RealURI) + ".gpg";
- Rename(LastGoodSigFile,VerifiedSigFile);
+ if (DestFile != SigFile)
+ {
+ string VerifiedSigFile = _config->FindDir("Dir::State::lists") +
+ URItoFileName(RealURI) + ".gpg";
+ Rename(LastGoodSigFile,VerifiedSigFile);
+ }
Status = StatTransientNetworkError;
_error->Warning(_("A error occurred during the signature "
"verification. The repository is not updated "
@@ -1347,6 +1525,35 @@ void pkgAcqMetaIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
QueueIndexes(false);
}
/*}}}*/
+pkgAcqMetaClearSig::pkgAcqMetaClearSig(pkgAcquire *Owner, /*{{{*/
+ string const &URI, string const &URIDesc, string const &ShortDesc,
+ string const &MetaIndexURI, string const &MetaIndexURIDesc, string const &MetaIndexShortDesc,
+ string const &MetaSigURI, string const &MetaSigURIDesc, string const &MetaSigShortDesc,
+ const vector<struct IndexTarget*>* IndexTargets,
+ indexRecords* MetaIndexParser) :
+ pkgAcqMetaIndex(Owner, URI, URIDesc, ShortDesc, "", IndexTargets, MetaIndexParser),
+ MetaIndexURI(MetaIndexURI), MetaIndexURIDesc(MetaIndexURIDesc), MetaIndexShortDesc(MetaIndexShortDesc),
+ MetaSigURI(MetaSigURI), MetaSigURIDesc(MetaSigURIDesc), MetaSigShortDesc(MetaSigShortDesc)
+{
+ SigFile = DestFile;
+}
+ /*}}}*/
+void pkgAcqMetaClearSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*{{{*/
+{
+ if (AuthPass == false)
+ {
+ new pkgAcqMetaSig(Owner,
+ MetaSigURI, MetaSigURIDesc, MetaSigShortDesc,
+ MetaIndexURI, MetaIndexURIDesc, MetaIndexShortDesc,
+ IndexTargets, MetaIndexParser);
+ if (Cnf->LocalOnly == true ||
+ StringToBool(LookupTag(Message, "Transient-Failure"), false) == false)
+ Dequeue();
+ }
+ else
+ pkgAcqMetaIndex::Failed(Message, Cnf);
+}
+ /*}}}*/
// AcqArchive::AcqArchive - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* This just sets up the initial fetch environment and queues the first
@@ -1793,3 +2000,13 @@ string pkgAcqFile::Custom600Headers()
return "";
}
/*}}}*/
+bool IndexTarget::IsOptional() const {
+ if (strncmp(ShortDesc.c_str(), "Translation", 11) != 0)
+ return false;
+ return true;
+}
+bool IndexTarget::IsSubIndex() const {
+ if (ShortDesc != "TranslationIndex")
+ return false;
+ return true;
+}
diff --git a/apt-pkg/acquire-item.h b/apt-pkg/acquire-item.h
index 943c61876..2ae7bf27c 100644
--- a/apt-pkg/acquire-item.h
+++ b/apt-pkg/acquire-item.h
@@ -287,6 +287,50 @@ struct DiffInfo {
unsigned long size;
};
/*}}}*/
+/** \brief An item that is responsible for fetching a SubIndex {{{
+ *
+ * The MetaIndex file includes only records for important indexes
+ * and records for these SubIndex files so these can carry records
+ * for addition files like PDiffs and Translations
+ */
+class pkgAcqSubIndex : public pkgAcquire::Item
+{
+ protected:
+ /** \brief If \b true, debugging information will be written to std::clog. */
+ bool Debug;
+
+ /** \brief The item that is currently being downloaded. */
+ pkgAcquire::ItemDesc Desc;
+
+ /** \brief The Hash that this file should have after download
+ */
+ HashString ExpectedHash;
+
+ public:
+ // Specialized action members
+ virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf);
+ virtual void Done(string Message,unsigned long Size,string Md5Hash,
+ pkgAcquire::MethodConfig *Cnf);
+ virtual string DescURI() {return Desc.URI;};
+ virtual string Custom600Headers();
+ virtual bool ParseIndex(string const &IndexFile);
+
+ /** \brief Create a new pkgAcqSubIndex.
+ *
+ * \param Owner The Acquire object that owns this item.
+ *
+ * \param URI The URI of the list file to download.
+ *
+ * \param URIDesc A long description of the list file to download.
+ *
+ * \param ShortDesc A short description of the list file to download.
+ *
+ * \param ExpectedHash The list file's MD5 signature.
+ */
+ pkgAcqSubIndex(pkgAcquire *Owner, string const &URI,string const &URIDesc,
+ string const &ShortDesc, HashString const &ExpectedHash);
+};
+ /*}}}*/
/** \brief An item that is responsible for fetching an index file of {{{
* package list diffs and starting the package list's download.
*
@@ -449,7 +493,7 @@ class pkgAcqIndexDiffs : public pkgAcquire::Item
StateFetchDiff,
/** \brief The diff is currently being uncompressed. */
- StateUnzipDiff,
+ StateUnzipDiff, // FIXME: No longer used
/** \brief The diff is currently being applied. */
StateApplyDiff
@@ -528,8 +572,8 @@ class pkgAcqIndex : public pkgAcquire::Item
/** \brief The expected hashsum of the decompressed index file. */
HashString ExpectedHash;
- /** \brief The compression-related file extension that is being
- * added to the downloaded file (e.g., ".gz" or ".bz2").
+ /** \brief The compression-related file extensions that are being
+ * added to the downloaded file one by one if first fails (e.g., "gz bz2").
*/
string CompressionExtension;
@@ -540,7 +584,7 @@ class pkgAcqIndex : public pkgAcquire::Item
virtual void Done(string Message,unsigned long Size,string Md5Hash,
pkgAcquire::MethodConfig *Cnf);
virtual string Custom600Headers();
- virtual string DescURI() {return RealURI + CompressionExtension;};
+ virtual string DescURI() {return Desc.URI;};
virtual string HashSum() {return ExpectedHash.toStr(); };
/** \brief Create a pkgAcqIndex.
@@ -565,6 +609,9 @@ class pkgAcqIndex : public pkgAcquire::Item
pkgAcqIndex(pkgAcquire *Owner,string URI,string URIDesc,
string ShortDesc, HashString ExpectedHash,
string compressExt="");
+ pkgAcqIndex(pkgAcquire *Owner, struct IndexTarget const * const Target,
+ HashString const &ExpectedHash, indexRecords const *MetaIndexParser);
+ void Init(string const &URI, string const &URIDesc, string const &ShortDesc);
};
/*}}}*/
/** \brief An acquire item that is responsible for fetching a {{{
@@ -594,6 +641,8 @@ class pkgAcqIndexTrans : public pkgAcqIndex
*/
pkgAcqIndexTrans(pkgAcquire *Owner,string URI,string URIDesc,
string ShortDesc);
+ pkgAcqIndexTrans(pkgAcquire *Owner, struct IndexTarget const * const Target,
+ HashString const &ExpectedHash, indexRecords const *MetaIndexParser);
};
/*}}}*/
/** \brief Information about an index file. */ /*{{{*/
@@ -612,8 +661,18 @@ struct IndexTarget
* looked up within the meta signature file.
*/
string MetaKey;
+
+ //FIXME: We should use virtual methods here instead…
+ bool IsOptional() const;
+ bool IsSubIndex() const;
+};
+ /*}}}*/
+/** \brief Information about an optional index file. */ /*{{{*/
+struct OptionalIndexTarget : public IndexTarget
+{
};
/*}}}*/
+
/** \brief An acquire item that downloads the detached signature {{{
* of a meta-index (Release) file, then queues up the release
* file itself.
@@ -772,6 +831,39 @@ class pkgAcqMetaIndex : public pkgAcquire::Item
indexRecords* MetaIndexParser);
};
/*}}}*/
+/** \brief An item repsonsible for downloading clearsigned metaindexes {{{*/
+class pkgAcqMetaClearSig : public pkgAcqMetaIndex
+{
+ /** \brief The URI of the meta-index file for the detached signature */
+ string MetaIndexURI;
+
+ /** \brief A "URI-style" description of the meta-index file */
+ string MetaIndexURIDesc;
+
+ /** \brief A brief description of the meta-index file */
+ string MetaIndexShortDesc;
+
+ /** \brief The URI of the detached meta-signature file if the clearsigned one failed. */
+ string MetaSigURI;
+
+ /** \brief A "URI-style" description of the meta-signature file */
+ string MetaSigURIDesc;
+
+ /** \brief A brief description of the meta-signature file */
+ string MetaSigShortDesc;
+
+public:
+ void Failed(string Message,pkgAcquire::MethodConfig *Cnf);
+
+ /** \brief Create a new pkgAcqMetaClearSig. */
+ pkgAcqMetaClearSig(pkgAcquire *Owner,
+ string const &URI, string const &URIDesc, string const &ShortDesc,
+ string const &MetaIndexURI, string const &MetaIndexURIDesc, string const &MetaIndexShortDesc,
+ string const &MetaSigURI, string const &MetaSigURIDesc, string const &MetaSigShortDesc,
+ const vector<struct IndexTarget*>* IndexTargets,
+ indexRecords* MetaIndexParser);
+};
+ /*}}}*/
/** \brief An item that is responsible for fetching a package file. {{{
*
* If the package file already exists in the cache, nothing will be
diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc
index 0fbce3c2a..0d26f8f66 100644
--- a/apt-pkg/algorithms.cc
+++ b/apt-pkg/algorithms.cc
@@ -162,7 +162,28 @@ bool pkgSimulate::Configure(PkgIterator iPkg)
}
}
-// Sim.MarkInstall(Pkg,false);
+ if (Sim[Pkg].InstBroken() == true)
+ {
+ /* We don't call Configure for Pseudo packages and if the 'all' is already installed
+ the simulation will think the pseudo package is not installed, so if something is
+ broken we walk over the dependencies and search for not installed pseudo packages */
+ for (pkgCache::DepIterator D = Sim[Pkg].InstVerIter(Sim).DependsList(); D.end() == false; D++)
+ {
+ if (Sim.IsImportantDep(D) == false ||
+ (Sim[D] & pkgDepCache::DepInstall) != 0)
+ continue;
+ pkgCache::PkgIterator T = D.TargetPkg();
+ if (T.end() == true || T->CurrentVer != 0 || Flags[T->ID] != 0)
+ continue;
+ pkgCache::PkgIterator A = T.Group().FindPkg("all");
+ if (A.end() == true || A->VersionList == 0 || A->CurrentVer == 0 ||
+ Cache.VS().CheckDep(A.CurVersion(), pkgCache::Dep::Equals, T.CandVersion()) == false)
+ continue;
+ Sim.MarkInstall(T, false);
+ Flags[T->ID] = 2;
+ }
+ }
+
if (Sim[Pkg].InstBroken() == true)
{
cout << "Conf " << Pkg.FullName(false) << " broken" << endl;
diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc
index 52f54073c..3cf4d2429 100644
--- a/apt-pkg/aptconfiguration.cc
+++ b/apt-pkg/aptconfiguration.cc
@@ -90,6 +90,14 @@ const Configuration::getCompressionTypes(bool const &Cached) {
types.push_back(Types->Tag);
}
+ // add the special "uncompressed" type
+ if (std::find(types.begin(), types.end(), "uncompressed") == types.end())
+ {
+ string const uncompr = _config->FindFile("Dir::Bin::uncompressed", "");
+ if (uncompr.empty() == true || FileExists(uncompr) == true)
+ types.push_back("uncompressed");
+ }
+
return types;
}
/*}}}*/
@@ -155,33 +163,6 @@ std::vector<std::string> const Configuration::getLanguages(bool const &All,
}
closedir(D);
- // get the environment language codes: LC_MESSAGES (and later LANGUAGE)
- // we extract both, a long and a short code and then we will
- // check if we actually need both (rare) or if the short is enough
- string const envMsg = string(Locale == 0 ? std::setlocale(LC_MESSAGES, NULL) : *Locale);
- size_t const lenShort = (envMsg.find('_') != string::npos) ? envMsg.find('_') : 2;
- size_t const lenLong = (envMsg.find_first_of(".@") != string::npos) ? envMsg.find_first_of(".@") : (lenShort + 3);
-
- string envLong = envMsg.substr(0,lenLong);
- string const envShort = envLong.substr(0,lenShort);
- bool envLongIncluded = true;
-
- // to save the servers from unneeded queries, we only try also long codes
- // for languages it is realistic to have a long code translation file…
- // TODO: Improve translation acquire system to drop them dynamic
- char const *needLong[] = { "cs", "en", "pt", "sv", "zh", NULL };
- if (envLong != envShort) {
- for (char const **l = needLong; *l != NULL; l++)
- if (envShort.compare(*l) == 0) {
- envLongIncluded = false;
- break;
- }
- }
-
- // we don't add the long code, but we allow the user to do so
- if (envLongIncluded == true)
- envLong.clear();
-
// FIXME: Remove support for the old APT::Acquire::Translation
// it was undocumented and so it should be not very widthly used
string const oldAcquire = _config->Find("APT::Acquire::Translation","");
@@ -203,12 +184,22 @@ std::vector<std::string> const Configuration::getLanguages(bool const &All,
return codes;
}
- // It is very likely we will need to environment codes later,
+ // get the environment language codes: LC_MESSAGES (and later LANGUAGE)
+ // we extract both, a long and a short code and then we will
+ // check if we actually need both (rare) or if the short is enough
+ string const envMsg = string(Locale == 0 ? std::setlocale(LC_MESSAGES, NULL) : *Locale);
+ size_t const lenShort = (envMsg.find('_') != string::npos) ? envMsg.find('_') : 2;
+ size_t const lenLong = (envMsg.find_first_of(".@") != string::npos) ? envMsg.find_first_of(".@") : (lenShort + 3);
+
+ string const envLong = envMsg.substr(0,lenLong);
+ string const envShort = envLong.substr(0,lenShort);
+
+ // It is very likely we will need the environment codes later,
// so let us generate them now from LC_MESSAGES and LANGUAGE
std::vector<string> environment;
if (envShort != "C") {
// take care of LC_MESSAGES
- if (envLongIncluded == false)
+ if (envLong != envShort)
environment.push_back(envLong);
environment.push_back(envShort);
// take care of LANGUAGE
@@ -225,16 +216,6 @@ std::vector<std::string> const Configuration::getLanguages(bool const &All,
continue;
if (std::find(environment.begin(), environment.end(), *e) != environment.end())
continue;
- if (e->find('_') != string::npos) {
- // Drop LongCodes here - ShortCodes are also included
- string const shorty = e->substr(0, e->find('_'));
- char const **n = needLong;
- for (; *n != NULL; ++n)
- if (shorty == *n)
- break;
- if (*n == NULL)
- continue;
- }
++addedLangs;
environment.push_back(*e);
}
diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h
index 26070636e..449d4b441 100644
--- a/apt-pkg/cacheiterators.h
+++ b/apt-pkg/cacheiterators.h
@@ -96,7 +96,7 @@ class pkgCache::GrpIterator: public Iterator<Group, GrpIterator> {
protected:
inline Group* OwnerPointer() const {
- return Owner->GrpP;
+ return (Owner != 0) ? Owner->GrpP : 0;
};
public:
@@ -137,7 +137,7 @@ class pkgCache::PkgIterator: public Iterator<Package, PkgIterator> {
protected:
inline Package* OwnerPointer() const {
- return Owner->PkgP;
+ return (Owner != 0) ? Owner->PkgP : 0;
};
public:
@@ -184,7 +184,7 @@ class pkgCache::PkgIterator: public Iterator<Package, PkgIterator> {
class pkgCache::VerIterator : public Iterator<Version, VerIterator> {
protected:
inline Version* OwnerPointer() const {
- return Owner->VerP;
+ return (Owner != 0) ? Owner->VerP : 0;
};
public:
@@ -241,7 +241,7 @@ class pkgCache::VerIterator : public Iterator<Version, VerIterator> {
class pkgCache::DescIterator : public Iterator<Description, DescIterator> {
protected:
inline Description* OwnerPointer() const {
- return Owner->DescP;
+ return (Owner != 0) ? Owner->DescP : 0;
};
public:
@@ -270,7 +270,7 @@ class pkgCache::DepIterator : public Iterator<Dependency, DepIterator> {
protected:
inline Dependency* OwnerPointer() const {
- return Owner->DepP;
+ return (Owner != 0) ? Owner->DepP : 0;
};
public:
@@ -315,7 +315,7 @@ class pkgCache::PrvIterator : public Iterator<Provides, PrvIterator> {
protected:
inline Provides* OwnerPointer() const {
- return Owner->ProvideP;
+ return (Owner != 0) ? Owner->ProvideP : 0;
};
public:
@@ -349,7 +349,7 @@ class pkgCache::PrvIterator : public Iterator<Provides, PrvIterator> {
class pkgCache::PkgFileIterator : public Iterator<PackageFile, PkgFileIterator> {
protected:
inline PackageFile* OwnerPointer() const {
- return Owner->PkgFileP;
+ return (Owner != 0) ? Owner->PkgFileP : 0;
};
public:
@@ -382,7 +382,7 @@ class pkgCache::PkgFileIterator : public Iterator<PackageFile, PkgFileIterator>
class pkgCache::VerFileIterator : public pkgCache::Iterator<VerFile, VerFileIterator> {
protected:
inline VerFile* OwnerPointer() const {
- return Owner->VerFileP;
+ return (Owner != 0) ? Owner->VerFileP : 0;
};
public:
@@ -401,7 +401,7 @@ class pkgCache::VerFileIterator : public pkgCache::Iterator<VerFile, VerFileIter
class pkgCache::DescFileIterator : public Iterator<DescFile, DescFileIterator> {
protected:
inline DescFile* OwnerPointer() const {
- return Owner->DescFileP;
+ return (Owner != 0) ? Owner->DescFileP : 0;
};
public:
diff --git a/apt-pkg/cdrom.cc b/apt-pkg/cdrom.cc
index 0e36f44a2..04ace10a6 100644
--- a/apt-pkg/cdrom.cc
+++ b/apt-pkg/cdrom.cc
@@ -198,7 +198,7 @@ int pkgCdrom::Score(string Path)
// a symlink gets a big penalty
struct stat Buf;
string statPath = flNotFile(Path);
- string cdromPath = _config->FindDir("Acquire::cdrom::mount","/cdrom/");
+ string cdromPath = _config->FindDir("Acquire::cdrom::mount");
while(statPath != cdromPath && statPath != "./") {
statPath.resize(statPath.size()-1); // remove the trailing '/'
if (lstat(statPath.c_str(),&Buf) == 0) {
@@ -509,7 +509,7 @@ bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log) /*{{{*/
stringstream msg;
// Startup
- string CDROM = _config->FindDir("Acquire::cdrom::mount","/cdrom/");
+ string CDROM = _config->FindDir("Acquire::cdrom::mount");
if (CDROM[0] == '.')
CDROM= SafeGetCWD() + '/' + CDROM;
@@ -568,7 +568,7 @@ bool pkgCdrom::Add(pkgCdromStatus *log) /*{{{*/
stringstream msg;
// Startup
- string CDROM = _config->FindDir("Acquire::cdrom::mount","/cdrom/");
+ string CDROM = _config->FindDir("Acquire::cdrom::mount");
if (CDROM[0] == '.')
CDROM= SafeGetCWD() + '/' + CDROM;
diff --git a/apt-pkg/contrib/error.cc b/apt-pkg/contrib/error.cc
index e2e8d6e57..7dad11689 100644
--- a/apt-pkg/contrib/error.cc
+++ b/apt-pkg/contrib/error.cc
@@ -18,6 +18,7 @@
#include <iostream>
#include <errno.h>
#include <stdio.h>
+#include <stdlib.h>
#include <unistd.h>
#include <string>
@@ -103,10 +104,21 @@ bool GlobalError::InsertErrno(MsgType const &type, const char *Function,
// GlobalError::InsertErrno - formats an error message with the errno /*{{{*/
bool GlobalError::InsertErrno(MsgType type, const char* Function,
const char* Description, va_list &args) {
- char S[400];
- snprintf(S, sizeof(S), "%s - %s (%i: %s)", Description,
- Function, errno, strerror(errno));
- return Insert(type, S, args);
+ int const errsv = errno;
+ char* S = (char*) malloc(400);
+ size_t const Ssize = snprintf(S, 400, "%s - %s (%i: %s)", Description,
+ Function, errsv, strerror(errsv)) + 1;
+
+ if (Ssize > 400) {
+ free(S);
+ S = (char*) malloc(Ssize);
+ snprintf(S, Ssize, "%s - %s (%i: %s)", Description,
+ Function, errsv, strerror(errsv));
+ }
+
+ bool const geins = Insert(type, S, args);
+ free(S);
+ return geins;
}
/*}}}*/
// GlobalError::Fatal - Add a fatal error to the list /*{{{*/
@@ -157,8 +169,14 @@ bool GlobalError::Insert(MsgType const &type, const char *Description,...)
// GlobalError::Insert - Insert a new item at the end /*{{{*/
bool GlobalError::Insert(MsgType type, const char* Description,
va_list &args) {
- char S[400];
- vsnprintf(S,sizeof(S),Description,args);
+ char* S = (char*) malloc(400);
+ size_t const Ssize = vsnprintf(S, 400, Description, args) + 1;
+
+ if (Ssize > 400) {
+ free(S);
+ S = (char*) malloc(Ssize);
+ vsnprintf(S, Ssize, Description, args);
+ }
Item const m(S, type);
Messages.push_back(m);
@@ -169,6 +187,7 @@ bool GlobalError::Insert(MsgType type, const char* Description,
if (type == FATAL || type == DEBUG)
std::clog << m << std::endl;
+ free(S);
return false;
}
/*}}}*/
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc
index f4ab066d7..52f517ee0 100644
--- a/apt-pkg/contrib/fileutl.cc
+++ b/apt-pkg/contrib/fileutl.cc
@@ -191,7 +191,7 @@ int GetLock(string File,bool Errors)
/*}}}*/
// FileExists - Check if a file exists /*{{{*/
// ---------------------------------------------------------------------
-/* */
+/* Beware: Directories are also files! */
bool FileExists(string File)
{
struct stat Buf;
@@ -200,6 +200,17 @@ bool FileExists(string File)
return true;
}
/*}}}*/
+// RealFileExists - Check if a file exists and if it is really a file /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool RealFileExists(string File)
+{
+ struct stat Buf;
+ if (stat(File.c_str(),&Buf) != 0)
+ return false;
+ return ((Buf.st_mode & S_IFREG) != 0);
+}
+ /*}}}*/
// DirectoryExists - Check if a directory exists and is really one /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -304,6 +315,13 @@ std::vector<string> GetListOfFilesInDir(string const &Dir, std::vector<string> c
}
std::vector<string> List;
+
+ if (DirectoryExists(Dir.c_str()) == false)
+ {
+ _error->Error(_("List of files can't be created as '%s' is not a directory"), Dir.c_str());
+ return List;
+ }
+
Configuration::MatchAgainstConfig SilentIgnore("Dir::Ignore-Files-Silently");
DIR *D = opendir(Dir.c_str());
if (D == 0)
@@ -318,6 +336,20 @@ std::vector<string> GetListOfFilesInDir(string const &Dir, std::vector<string> c
if (Ent->d_name[0] == '.')
continue;
+ // Make sure it is a file and not something else
+ string const File = flCombine(Dir,Ent->d_name);
+#ifdef _DIRENT_HAVE_D_TYPE
+ if (Ent->d_type != DT_REG)
+#endif
+ {
+ if (RealFileExists(File.c_str()) == false)
+ {
+ if (SilentIgnore.Match(Ent->d_name) == false)
+ _error->Notice(_("Ignoring '%s' in directory '%s' as it is not a regular file"), Ent->d_name, Dir.c_str());
+ continue;
+ }
+ }
+
// check for accepted extension:
// no extension given -> periods are bad as hell!
// extensions given -> "" extension allows no extension
@@ -331,7 +363,7 @@ std::vector<string> GetListOfFilesInDir(string const &Dir, std::vector<string> c
if (Debug == true)
std::clog << "Bad file: " << Ent->d_name << " → no extension" << std::endl;
if (SilentIgnore.Match(Ent->d_name) == false)
- _error->Notice("Ignoring file '%s' in directory '%s' as it has no filename extension", Ent->d_name, Dir.c_str());
+ _error->Notice(_("Ignoring file '%s' in directory '%s' as it has no filename extension"), Ent->d_name, Dir.c_str());
continue;
}
}
@@ -340,7 +372,7 @@ std::vector<string> GetListOfFilesInDir(string const &Dir, std::vector<string> c
if (Debug == true)
std::clog << "Bad file: " << Ent->d_name << " → bad extension »" << flExtension(Ent->d_name) << "«" << std::endl;
if (SilentIgnore.Match(Ent->d_name) == false)
- _error->Notice("Ignoring file '%s' in directory '%s' as it has an invalid filename extension", Ent->d_name, Dir.c_str());
+ _error->Notice(_("Ignoring file '%s' in directory '%s' as it has an invalid filename extension"), Ent->d_name, Dir.c_str());
continue;
}
}
@@ -373,16 +405,6 @@ std::vector<string> GetListOfFilesInDir(string const &Dir, std::vector<string> c
continue;
}
- // Make sure it is a file and not something else
- string const File = flCombine(Dir,Ent->d_name);
- struct stat St;
- if (stat(File.c_str(),&St) != 0 || S_ISREG(St.st_mode) == 0)
- {
- if (Debug == true)
- std::clog << "Bad file: " << Ent->d_name << " → stat says not a good file" << std::endl;
- continue;
- }
-
if (Debug == true)
std::clog << "Accept file: " << Ent->d_name << " in " << Dir << std::endl;
List.push_back(File);
diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h
index 1380f06b4..cde288ad2 100644
--- a/apt-pkg/contrib/fileutl.h
+++ b/apt-pkg/contrib/fileutl.h
@@ -72,6 +72,7 @@ class FileFd
// Simple manipulators
inline int Fd() {return iFd;};
inline void Fd(int fd) {iFd = fd;};
+ inline gzFile gzFd() {return gz;};
inline bool IsOpen() {return iFd >= 0;};
inline bool Failed() {return (Flags & Fail) == Fail;};
inline void EraseOnFailure() {Flags |= DelOnFail;};
@@ -93,6 +94,7 @@ bool RunScripts(const char *Cnf);
bool CopyFile(FileFd &From,FileFd &To);
int GetLock(string File,bool Errors = true);
bool FileExists(string File);
+bool RealFileExists(string File);
bool DirectoryExists(string const &Path) __attrib_const;
bool CreateDirectory(string const &Parent, string const &Path);
diff --git a/apt-pkg/contrib/progress.cc b/apt-pkg/contrib/progress.cc
index cffdddc4f..45e81edcb 100644
--- a/apt-pkg/contrib/progress.cc
+++ b/apt-pkg/contrib/progress.cc
@@ -135,7 +135,7 @@ bool OpProgress::CheckChange(float Interval)
OpTextProgress::OpTextProgress(Configuration &Config) :
NoUpdate(false), NoDisplay(false), LastLen(0)
{
- if (Config.FindI("quiet",0) >= 1)
+ if (Config.FindI("quiet",0) >= 1 || Config.FindB("quiet::NoUpdate", false) == true)
NoUpdate = true;
if (Config.FindI("quiet",0) >= 2)
NoDisplay = true;
diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc
index c2b335ed7..2e2bb5ebc 100644
--- a/apt-pkg/contrib/strutl.cc
+++ b/apt-pkg/contrib/strutl.cc
@@ -968,6 +968,23 @@ bool StrToNum(const char *Str,unsigned long &Res,unsigned Len,unsigned Base)
return true;
}
/*}}}*/
+// Base256ToNum - Convert a fixed length binary to a number /*{{{*/
+// ---------------------------------------------------------------------
+/* This is used in decoding the 256bit encoded fixed length fields in
+ tar files */
+bool Base256ToNum(const char *Str,unsigned long &Res,unsigned int Len)
+{
+ if ((Str[0] & 0x80) == 0)
+ return false;
+ else
+ {
+ Res = Str[0] & 0x7F;
+ for(unsigned int i = 1; i < Len; ++i)
+ Res = (Res<<8) + Str[i];
+ return true;
+ }
+}
+ /*}}}*/
// HexDigit - Convert a hex character into an integer /*{{{*/
// ---------------------------------------------------------------------
/* Helper for Hex2Num */
diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h
index 14cf5c943..89cbf0370 100644
--- a/apt-pkg/contrib/strutl.h
+++ b/apt-pkg/contrib/strutl.h
@@ -52,6 +52,7 @@ string LookupTag(const string &Message,const char *Tag,const char *Default = 0);
int StringToBool(const string &Text,int Default = -1);
bool ReadMessages(int Fd, vector<string> &List);
bool StrToNum(const char *Str,unsigned long &Res,unsigned Len,unsigned Base = 0);
+bool Base256ToNum(const char *Str,unsigned long &Res,unsigned int Len);
bool Hex2Num(const string &Str,unsigned char *Num,unsigned int Length);
bool TokSplitString(char Tok,char *Input,char **List,
unsigned long ListMax);
diff --git a/apt-pkg/contrib/weakptr.h b/apt-pkg/contrib/weakptr.h
index 5158e393c..8de727d89 100644
--- a/apt-pkg/contrib/weakptr.h
+++ b/apt-pkg/contrib/weakptr.h
@@ -22,6 +22,8 @@
#define WEAK_POINTER_H
#include <set>
+#include <stddef.h>
+
/**
* Class for objects providing support for weak pointers.
*
diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc
index af1209ccb..9961b5ae4 100644
--- a/apt-pkg/deb/debindexfile.cc
+++ b/apt-pkg/deb/debindexfile.cc
@@ -324,8 +324,14 @@ bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
return _error->Error("Problem with MergeList %s",PackageFile.c_str());
// Check the release file
- string ReleaseFile = debReleaseIndex(URI,Dist).MetaIndexFile("Release");
+ string ReleaseFile = debReleaseIndex(URI,Dist).MetaIndexFile("InRelease");
+ bool releaseExists = false;
if (FileExists(ReleaseFile) == true)
+ releaseExists = true;
+ else
+ ReleaseFile = debReleaseIndex(URI,Dist).MetaIndexFile("Release");
+
+ if (releaseExists == true || FileExists(ReleaseFile) == true)
{
FileFd Rel(ReleaseFile,FileFd::ReadOnly);
if (_error->PendingError() == true)
diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc
index 1b3bfd6ae..9201e6a54 100644
--- a/apt-pkg/deb/deblistparser.cc
+++ b/apt-pkg/deb/deblistparser.cc
@@ -783,45 +783,89 @@ bool debListParser::Step()
bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,
FileFd &File, string component)
{
- pkgTagFile Tags(&File, File.Size() + 256); // XXX
- pkgTagSection Section;
- if (Tags.Step(Section) == false)
- return false;
-
- // FIXME: Do we need it now for multi-arch?
- // mvo: I don't think we need to fill that in (it's unused since apt-0.6)
-// FileI->Architecture = WriteUniqString(Arch);
-
// apt-secure does no longer download individual (per-section) Release
// file. to provide Component pinning we use the section name now
FileI->Component = WriteUniqString(component);
- const char *Start;
- const char *Stop;
- if (Section.Find("Suite",Start,Stop) == true)
- FileI->Archive = WriteUniqString(Start,Stop - Start);
- if (Section.Find("Component",Start,Stop) == true)
- FileI->Component = WriteUniqString(Start,Stop - Start);
- if (Section.Find("Version",Start,Stop) == true)
- FileI->Version = WriteUniqString(Start,Stop - Start);
- if (Section.Find("Origin",Start,Stop) == true)
- FileI->Origin = WriteUniqString(Start,Stop - Start);
- if (Section.Find("Codename",Start,Stop) == true)
- FileI->Codename = WriteUniqString(Start,Stop - Start);
- if (Section.Find("Label",Start,Stop) == true)
- FileI->Label = WriteUniqString(Start,Stop - Start);
- if (Section.Find("Architecture",Start,Stop) == true)
- FileI->Architecture = WriteUniqString(Start,Stop - Start);
-
- if (Section.FindFlag("NotAutomatic",FileI->Flags,
- pkgCache::Flag::NotAutomatic) == false)
- _error->Warning("Bad NotAutomatic flag");
- if (Section.FindFlag("ButAutomaticUpgrades",FileI->Flags,
- pkgCache::Flag::ButAutomaticUpgrades) == false)
- _error->Warning("Bad ButAutomaticUpgrades flag");
- // overrule the NotAutomatic setting if needed as they are both present for compatibility
- else if ((FileI->Flags & pkgCache::Flag::ButAutomaticUpgrades) == pkgCache::Flag::ButAutomaticUpgrades)
- FileI->Flags &= ~pkgCache::Flag::NotAutomatic;
+ FILE* release = fdopen(dup(File.Fd()), "r");
+ if (release == NULL)
+ return false;
+
+ char buffer[101];
+ bool gpgClose = false;
+ while (fgets(buffer, sizeof(buffer), release) != NULL)
+ {
+ size_t len = 0;
+
+ // Skip empty lines
+ for (; buffer[len] == '\r' && buffer[len] == '\n'; ++len);
+ if (buffer[len] == '\0')
+ continue;
+
+ // only evalute the first GPG section
+ if (strncmp("-----", buffer, 5) == 0)
+ {
+ if (gpgClose == true)
+ break;
+ gpgClose = true;
+ continue;
+ }
+
+ // seperate the tag from the data
+ for (; buffer[len] != ':' && buffer[len] != '\0'; ++len);
+ if (buffer[len] == '\0')
+ continue;
+ char* dataStart = buffer + len;
+ for (++dataStart; *dataStart == ' '; ++dataStart);
+ char* dataEnd = dataStart;
+ for (++dataEnd; *dataEnd != '\0'; ++dataEnd);
+
+ // which datastorage need to be updated
+ map_ptrloc* writeTo = NULL;
+ if (buffer[0] == ' ')
+ ;
+ #define APT_PARSER_WRITETO(X, Y) else if (strncmp(Y, buffer, len) == 0) writeTo = &X;
+ APT_PARSER_WRITETO(FileI->Archive, "Suite")
+ APT_PARSER_WRITETO(FileI->Component, "Component")
+ APT_PARSER_WRITETO(FileI->Version, "Version")
+ APT_PARSER_WRITETO(FileI->Origin, "Origin")
+ APT_PARSER_WRITETO(FileI->Codename, "Codename")
+ APT_PARSER_WRITETO(FileI->Label, "Label")
+ #undef APT_PARSER_WRITETO
+ #define APT_PARSER_FLAGIT(X) else if (strncmp(#X, buffer, len) == 0) \
+ pkgTagSection::FindFlag(FileI->Flags, pkgCache::Flag:: X, dataStart, dataEnd-1);
+ APT_PARSER_FLAGIT(NotAutomatic)
+ APT_PARSER_FLAGIT(ButAutomaticUpgrades)
+ #undef APT_PARSER_FLAGIT
+
+ // load all data from the line and save it
+ string data;
+ if (writeTo != NULL)
+ data.append(dataStart, dataEnd);
+ if (sizeof(buffer) - 1 == (dataEnd - buffer))
+ {
+ while (fgets(buffer, sizeof(buffer), release) != NULL)
+ {
+ if (writeTo != NULL)
+ data.append(buffer);
+ if (strlen(buffer) != sizeof(buffer) - 1)
+ break;
+ }
+ }
+ if (writeTo != NULL)
+ {
+ // remove spaces and stuff from the end of the data line
+ for (std::string::reverse_iterator s = data.rbegin();
+ s != data.rend(); ++s)
+ {
+ if (*s != '\r' && *s != '\n' && *s != ' ')
+ break;
+ *s = '\0';
+ }
+ *writeTo = WriteUniqString(data);
+ }
+ }
+ fclose(release);
return !_error->PendingError();
}
diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc
index 717d0bcde..a6edab6b9 100644
--- a/apt-pkg/deb/debmetaindex.cc
+++ b/apt-pkg/deb/debmetaindex.cc
@@ -119,6 +119,29 @@ string debReleaseIndex::SourceIndexURI(const char *Type, const string &Section)
return URI + "dists/" + Dist + "/" + SourceIndexURISuffix(Type, Section);
}
+string debReleaseIndex::TranslationIndexURISuffix(const char *Type, const string &Section) const
+{
+ string Res ="";
+ if (Dist[Dist.size() - 1] != '/')
+ Res += Section + "/i18n/";
+ return Res + Type;
+}
+
+string debReleaseIndex::TranslationIndexURI(const char *Type, const string &Section) const
+{
+ string Res;
+ if (Dist[Dist.size() - 1] == '/')
+ {
+ if (Dist != "/")
+ Res = URI + Dist;
+ else
+ Res = URI;
+ return Res + Type;
+ }
+ else
+ return URI + "dists/" + Dist + "/" + TranslationIndexURISuffix(Type, Section);
+}
+
debReleaseIndex::debReleaseIndex(string const &URI, string const &Dist) {
this->URI = URI;
this->Dist = Dist;
@@ -155,6 +178,7 @@ vector <struct IndexTarget *>* debReleaseIndex::ComputeIndexTargets() const {
if (IndexTargets->empty() == false && ArchEntries.size() == 1)
return IndexTargets;
+ std::set<std::string> sections;
for (map<string, vector<debSectionEntry const*> >::const_iterator a = ArchEntries.begin();
a != ArchEntries.end(); ++a) {
if (a->first == "source")
@@ -167,6 +191,37 @@ vector <struct IndexTarget *>* debReleaseIndex::ComputeIndexTargets() const {
Target->URI = IndexURI(Target->ShortDesc.c_str(), (*I)->Section, a->first);
Target->Description = Info (Target->ShortDesc.c_str(), (*I)->Section, a->first);
IndexTargets->push_back (Target);
+ sections.insert((*I)->Section);
+ }
+ }
+
+ // get the Translations:
+ // - if its a dists-style repository get the i18n/Index first
+ // - if its flat try to acquire files by guessing
+ if (Dist[Dist.size() - 1] == '/') {
+ std::vector<std::string> const lang = APT::Configuration::getLanguages(true);
+ for (std::set<std::string>::const_iterator s = sections.begin();
+ s != sections.end(); ++s) {
+ for (std::vector<std::string>::const_iterator l = lang.begin();
+ l != lang.end(); l++) {
+ if (*l == "none") continue;
+ IndexTarget * Target = new OptionalIndexTarget();
+ Target->ShortDesc = "Translation-" + *l;
+ Target->MetaKey = TranslationIndexURISuffix(l->c_str(), *s);
+ Target->URI = TranslationIndexURI(l->c_str(), *s);
+ Target->Description = Info (Target->ShortDesc.c_str(), *s);
+ IndexTargets->push_back(Target);
+ }
+ }
+ } else {
+ for (std::set<std::string>::const_iterator s = sections.begin();
+ s != sections.end(); ++s) {
+ IndexTarget * Target = new OptionalIndexTarget();
+ Target->ShortDesc = "TranslationIndex";
+ Target->MetaKey = TranslationIndexURISuffix("Index", *s);
+ Target->URI = TranslationIndexURI("Index", *s);
+ Target->Description = Info (Target->ShortDesc.c_str(), *s);
+ IndexTargets->push_back (Target);
}
}
@@ -182,58 +237,34 @@ bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll) const
new pkgAcqIndex(Owner, (*Target)->URI, (*Target)->Description,
(*Target)->ShortDesc, HashString());
}
- // this is normally created in pkgAcqMetaSig, but if we run
- // in --print-uris mode, we add it here
- new pkgAcqMetaIndex(Owner, MetaIndexURI("Release"),
- MetaIndexInfo("Release"), "Release",
- MetaIndexURI("Release.gpg"),
- ComputeIndexTargets(),
- new indexRecords (Dist));
-
}
- new pkgAcqMetaSig(Owner, MetaIndexURI("Release.gpg"),
- MetaIndexInfo("Release.gpg"), "Release.gpg",
- MetaIndexURI("Release"), MetaIndexInfo("Release"), "Release",
- ComputeIndexTargets(),
- new indexRecords (Dist));
-
- // Queue the translations
- std::vector<std::string> const lang = APT::Configuration::getLanguages(true);
- map<string, set<string> > sections;
- for (map<string, vector<debSectionEntry const*> >::const_iterator a = ArchEntries.begin();
- a != ArchEntries.end(); ++a) {
- if (a->first == "source")
- continue;
- for (vector<debSectionEntry const*>::const_iterator I = a->second.begin();
- I != a->second.end(); I++)
- sections[(*I)->Section].insert(lang.begin(), lang.end());
- }
-
- for (map<string, set<string> >::const_iterator s = sections.begin();
- s != sections.end(); ++s)
- for (set<string>::const_iterator l = s->second.begin();
- l != s->second.end(); l++) {
- if (*l == "none") continue;
- debTranslationsIndex i = debTranslationsIndex(URI,Dist,s->first,(*l).c_str());
- i.GetIndexes(Owner);
- }
+ new pkgAcqMetaClearSig(Owner, MetaIndexURI("InRelease"),
+ MetaIndexInfo("InRelease"), "InRelease",
+ MetaIndexURI("Release"), MetaIndexInfo("Release"), "Release",
+ MetaIndexURI("Release.gpg"), MetaIndexInfo("Release.gpg"), "Release.gpg",
+ ComputeIndexTargets(),
+ new indexRecords (Dist));
return true;
}
bool debReleaseIndex::IsTrusted() const
{
- string VerifiedSigFile = _config->FindDir("Dir::State::lists") +
- URItoFileName(MetaIndexURI("Release")) + ".gpg";
-
if(_config->FindB("APT::Authentication::TrustCDROM", false))
if(URI.substr(0,strlen("cdrom:")) == "cdrom:")
return true;
-
+
+ string VerifiedSigFile = _config->FindDir("Dir::State::lists") +
+ URItoFileName(MetaIndexURI("Release")) + ".gpg";
+
if (FileExists(VerifiedSigFile))
return true;
- return false;
+
+ VerifiedSigFile = _config->FindDir("Dir::State::lists") +
+ URItoFileName(MetaIndexURI("InRelease"));
+
+ return FileExists(VerifiedSigFile);
}
vector <pkgIndexFile *> *debReleaseIndex::GetIndexFiles() {
diff --git a/apt-pkg/deb/debmetaindex.h b/apt-pkg/deb/debmetaindex.h
index 360fa5419..1561c6e00 100644
--- a/apt-pkg/deb/debmetaindex.h
+++ b/apt-pkg/deb/debmetaindex.h
@@ -37,6 +37,8 @@ class debReleaseIndex : public metaIndex {
string IndexURISuffix(const char *Type, string const &Section, string const &Arch="native") const;
string SourceIndexURI(const char *Type, const string &Section) const;
string SourceIndexURISuffix(const char *Type, const string &Section) const;
+ string TranslationIndexURI(const char *Type, const string &Section) const;
+ string TranslationIndexURISuffix(const char *Type, const string &Section) const;
virtual vector <pkgIndexFile *> *GetIndexFiles();
virtual bool IsTrusted() const;
diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc
index cca590a63..f56e258e3 100644
--- a/apt-pkg/deb/dpkgpm.cc
+++ b/apt-pkg/deb/dpkgpm.cc
@@ -322,7 +322,6 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf)
return _error->Errno("fdopen","Faild to open new FD");
// Feed it the filenames.
- bool Die = false;
if (Version <= 1)
{
for (vector<Item>::iterator I = List.begin(); I != List.end(); I++)
@@ -339,14 +338,11 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf)
into the pipe. */
fprintf(F,"%s\n",I->File.c_str());
if (ferror(F) != 0)
- {
- Die = true;
break;
- }
}
}
else
- Die = !SendV2Pkgs(F);
+ SendV2Pkgs(F);
fclose(F);
@@ -1230,7 +1226,7 @@ bool pkgDPkgPM::Go(int OutStatusFd)
strprintf(dpkg_error, "Sub-process %s exited unexpectedly",Args[0]);
if(dpkg_error.size() > 0)
- _error->Error(dpkg_error.c_str());
+ _error->Error("%s", dpkg_error.c_str());
if(stopOnError)
{
@@ -1427,7 +1423,7 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg)
{
while( fgets(buf, sizeof(buf), log) != NULL)
fprintf(report, " %s", buf);
- fclose(log);
+ pclose(log);
}
}
@@ -1443,7 +1439,7 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg)
{
while( fgets(buf, sizeof(buf), log) != NULL)
fprintf(report, " %s", buf);
- fclose(log);
+ pclose(log);
}
}
diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc
index 72bdd3199..4c12a4fe1 100644
--- a/apt-pkg/depcache.cc
+++ b/apt-pkg/depcache.cc
@@ -10,6 +10,7 @@
// Include Files /*{{{*/
#include <apt-pkg/depcache.h>
#include <apt-pkg/version.h>
+#include <apt-pkg/versionmatch.h>
#include <apt-pkg/error.h>
#include <apt-pkg/sptr.h>
#include <apt-pkg/algorithms.h>
@@ -166,7 +167,7 @@ bool pkgDepCache::readStateFile(OpProgress *Prog) /*{{{*/
{
FileFd state_file;
string const state = _config->FindFile("Dir::State::extended_states");
- if(FileExists(state)) {
+ if(RealFileExists(state)) {
state_file.Open(state, FileFd::ReadOnly);
int const file_size = state_file.Size();
if(Prog != NULL)
@@ -225,7 +226,7 @@ bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly) /*{{{*/
string const state = _config->FindFile("Dir::State::extended_states");
// if it does not exist, create a empty one
- if(!FileExists(state))
+ if(!RealFileExists(state))
{
StateFile.Open(state, FileFd::WriteAtomic);
StateFile.Close();
@@ -338,7 +339,7 @@ bool pkgDepCache::CheckDep(DepIterator Dep,int Type,PkgIterator &Res)
/* Check simple depends. A depends -should- never self match but
we allow it anyhow because dpkg does. Technically it is a packaging
bug. Conflicts may never self match */
- if (Dep.TargetPkg()->Group != Dep.ParentPkg()->Group ||
+ if (Dep.TargetPkg() != Dep.ParentPkg() ||
(Dep->Type != Dep::Conflicts && Dep->Type != Dep::DpkgBreaks && Dep->Type != Dep::Obsoletes))
{
PkgIterator Pkg = Dep.TargetPkg();
@@ -1333,8 +1334,6 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
for (DepIterator D = instVer.DependsList(); D.end() != true; D++)
{
//FIXME: deal better with or-groups(?)
- DepIterator LocalStart = D;
-
if(IsImportantDep(D) && !D.IsCritical() &&
Start.TargetPkg() == D.TargetPkg())
{
@@ -1514,15 +1513,19 @@ void pkgDepCache::SetReInstall(PkgIterator const &Pkg,bool To)
/* */
void pkgDepCache::SetCandidateVersion(VerIterator TargetVer, bool const &Pseudo)
{
- ActionGroup group(*this);
pkgCache::PkgIterator Pkg = TargetVer.ParentPkg();
StateCache &P = PkgState[Pkg->ID];
+ if (P.CandidateVer == TargetVer)
+ return;
+
+ ActionGroup group(*this);
+
RemoveSizes(Pkg);
RemoveStates(Pkg);
- if (P.CandidateVer == P.InstallVer)
+ if (P.CandidateVer == P.InstallVer && P.Install() == true)
P.InstallVer = (Version *)TargetVer;
P.CandidateVer = (Version *)TargetVer;
P.Update(Pkg,*this);
@@ -1553,7 +1556,171 @@ void pkgDepCache::SetCandidateVersion(VerIterator TargetVer, bool const &Pseudo)
}
}
}
+ /*}}}*/
+// DepCache::SetCandidateRelease - Change the candidate version /*{{{*/
+// ---------------------------------------------------------------------
+/* changes the candidate of a package and walks over all its dependencies
+ to check if it needs to change the candidate of the dependency, too,
+ to reach a installable versionstate */
+bool pkgDepCache::SetCandidateRelease(pkgCache::VerIterator TargetVer,
+ std::string const &TargetRel)
+{
+ std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> > Changed;
+ return SetCandidateRelease(TargetVer, TargetRel, Changed);
+}
+bool pkgDepCache::SetCandidateRelease(pkgCache::VerIterator TargetVer,
+ std::string const &TargetRel,
+ std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> > &Changed)
+{
+ ActionGroup group(*this);
+ SetCandidateVersion(TargetVer);
+
+ if (TargetRel == "installed" || TargetRel == "candidate") // both doesn't make sense in this context
+ return true;
+
+ pkgVersionMatch Match(TargetRel, pkgVersionMatch::Release);
+ // save the position of the last element we will not undo - if we have to
+ std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> >::iterator newChanged = --(Changed.end());
+
+ for (pkgCache::DepIterator D = TargetVer.DependsList(); D.end() == false; ++D)
+ {
+ if (D->Type != pkgCache::Dep::PreDepends && D->Type != pkgCache::Dep::Depends &&
+ ((D->Type != pkgCache::Dep::Recommends && D->Type != pkgCache::Dep::Suggests) ||
+ IsImportantDep(D) == false))
+ continue;
+
+ // walk over an or-group and check if we need to do anything
+ // for simpilicity no or-group is handled as a or-group including one dependency
+ pkgCache::DepIterator Start = D;
+ bool itsFine = false;
+ for (bool stillOr = true; stillOr == true; ++Start)
+ {
+ stillOr = (Start->CompareOp & Dep::Or) == Dep::Or;
+ pkgCache::PkgIterator const P = Start.TargetPkg();
+ // virtual packages can't be a solution
+ if (P.end() == true || (P->ProvidesList == 0 && P->VersionList == 0))
+ continue;
+ pkgCache::VerIterator const Cand = PkgState[P->ID].CandidateVerIter(*this);
+ // no versioned dependency - but is it installable?
+ if (Start.TargetVer() == 0 || Start.TargetVer()[0] == '\0')
+ {
+ // Check if one of the providers is installable
+ if (P->ProvidesList != 0)
+ {
+ pkgCache::PrvIterator Prv = P.ProvidesList();
+ for (; Prv.end() == false; ++Prv)
+ {
+ pkgCache::VerIterator const C = PkgState[Prv.OwnerPkg()->ID].CandidateVerIter(*this);
+ if (C.end() == true || C != Prv.OwnerVer() ||
+ (VersionState(C.DependsList(), DepInstall, DepCandMin, DepCandPolicy) & DepCandMin) != DepCandMin)
+ continue;
+ break;
+ }
+ if (Prv.end() == true)
+ continue;
+ }
+ // no providers, so check if we have an installable candidate version
+ else if (Cand.end() == true ||
+ (VersionState(Cand.DependsList(), DepInstall, DepCandMin, DepCandPolicy) & DepCandMin) != DepCandMin)
+ continue;
+ itsFine = true;
+ break;
+ }
+ if (Cand.end() == true)
+ continue;
+ // check if the current candidate is enough for the versioned dependency - and installable?
+ if (VS().CheckDep(P.CandVersion(), Start->CompareOp, Start.TargetVer()) == true &&
+ (VersionState(Cand.DependsList(), DepInstall, DepCandMin, DepCandPolicy) & DepCandMin) == DepCandMin)
+ {
+ itsFine = true;
+ break;
+ }
+ }
+
+ if (itsFine == true) {
+ // something in the or-group was fine, skip all other members
+ for (; (D->CompareOp & Dep::Or) == Dep::Or; ++D);
+ continue;
+ }
+
+ // walk again over the or-group and check each if a candidate switch would help
+ itsFine = false;
+ for (bool stillOr = true; stillOr == true; ++D)
+ {
+ stillOr = (D->CompareOp & Dep::Or) == Dep::Or;
+ // changing candidate will not help if the dependency is not versioned
+ if (D.TargetVer() == 0 || D.TargetVer()[0] == '\0')
+ {
+ if (stillOr == true)
+ continue;
+ break;
+ }
+
+ pkgCache::VerIterator V;
+ if (TargetRel == "newest")
+ V = D.TargetPkg().VersionList();
+ else
+ V = Match.Find(D.TargetPkg());
+
+ // check if the version from this release could satisfy the dependency
+ if (V.end() == true || VS().CheckDep(V.VerStr(), D->CompareOp, D.TargetVer()) == false)
+ {
+ if (stillOr == true)
+ continue;
+ break;
+ }
+
+ pkgCache::VerIterator oldCand = PkgState[D.TargetPkg()->ID].CandidateVerIter(*this);
+ if (V == oldCand)
+ {
+ // Do we already touched this Version? If so, their versioned dependencies are okay, no need to check again
+ for (std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> >::const_iterator c = Changed.begin();
+ c != Changed.end(); ++c)
+ {
+ if (c->first->ParentPkg != V->ParentPkg)
+ continue;
+ itsFine = true;
+ break;
+ }
+ }
+
+ if (itsFine == false)
+ {
+ // change the candidate
+ Changed.push_back(make_pair(oldCand, TargetVer));
+ if (SetCandidateRelease(V, TargetRel, Changed) == false)
+ {
+ if (stillOr == false)
+ break;
+ // undo the candidate changing
+ SetCandidateVersion(oldCand);
+ Changed.pop_back();
+ continue;
+ }
+ itsFine = true;
+ }
+
+ // something in the or-group was fine, skip all other members
+ for (; (D->CompareOp & Dep::Or) == Dep::Or; ++D);
+ break;
+ }
+ if (itsFine == false && (D->Type == pkgCache::Dep::PreDepends || D->Type == pkgCache::Dep::Depends))
+ {
+ // undo all changes which aren't lead to a solution
+ for (std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> >::const_iterator c = ++newChanged;
+ c != Changed.end(); ++c)
+ SetCandidateVersion(c->first);
+ Changed.erase(newChanged, Changed.end());
+ return false;
+ }
+ }
+ return true;
+}
+ /*}}}*/
+// DepCache::MarkAuto - set the Auto flag for a package /*{{{*/
+// ---------------------------------------------------------------------
+/* */
void pkgDepCache::MarkAuto(const PkgIterator &Pkg, bool Auto)
{
StateCache &state = PkgState[Pkg->ID];
@@ -1756,10 +1923,11 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg,
return;
VerIterator const currver = pkg.CurrentVer();
- VerIterator const candver = state.CandidateVerIter(*this);
VerIterator const instver = state.InstVerIter(*this);
#if 0
+ VerIterator const candver = state.CandidateVerIter(*this);
+
// If a package was garbage-collected but is now being marked, we
// should re-select it
// For cases when a pkg is set to upgrade and this trigger the
diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h
index 2d3dbdf77..dba3e22dc 100644
--- a/apt-pkg/depcache.h
+++ b/apt-pkg/depcache.h
@@ -396,6 +396,25 @@ class pkgDepCache : protected pkgCache::Namespace
void SetReInstall(PkgIterator const &Pkg,bool To);
void SetCandidateVersion(VerIterator TargetVer, bool const &Pseudo = true);
+ bool SetCandidateRelease(pkgCache::VerIterator TargetVer,
+ std::string const &TargetRel);
+ /** Set the candidate version for dependencies too if needed.
+ *
+ * Sets not only the candidate version as SetCandidateVersion does,
+ * but walks also down the dependency tree and checks if it is required
+ * to set the candidate of the dependency to a version from the given
+ * release, too.
+ *
+ * \param TargetVer new candidate version of the package
+ * \param TargetRel try to switch to this release if needed
+ * \param[out] Changed a list of pairs consisting of the \b old
+ * version of the changed package and the version which
+ * required the switch of this dependency
+ * \return \b true if the switch was successful, \b false otherwise
+ */
+ bool SetCandidateRelease(pkgCache::VerIterator TargetVer,
+ std::string const &TargetRel,
+ std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> > &Changed);
/** Set the "is automatically installed" flag of Pkg. */
void MarkAuto(const PkgIterator &Pkg, bool Auto);
diff --git a/apt-pkg/indexcopy.cc b/apt-pkg/indexcopy.cc
index f88d51fc5..c2ee1c347 100644
--- a/apt-pkg/indexcopy.cc
+++ b/apt-pkg/indexcopy.cc
@@ -722,7 +722,8 @@ bool SigVerify::RunGPGV(std::string const &File, std::string const &FileGPG,
}
Args.push_back(FileGPG.c_str());
- Args.push_back(File.c_str());
+ if (FileGPG != File)
+ Args.push_back(File.c_str());
Args.push_back(NULL);
if (Debug == true)
diff --git a/apt-pkg/indexrecords.cc b/apt-pkg/indexrecords.cc
index eb9a36866..10e154ad2 100644
--- a/apt-pkg/indexrecords.cc
+++ b/apt-pkg/indexrecords.cc
@@ -55,14 +55,17 @@ bool indexRecords::Load(const string Filename) /*{{{*/
}
pkgTagSection Section;
- if (TagFile.Step(Section) == false)
- {
- strprintf(ErrorText, _("No sections in Release file %s"), Filename.c_str());
- return false;
- }
-
const char *Start, *End;
- Section.Get (Start, End, 0);
+ // Skip over sections beginning with ----- as this is an idicator for clearsigns
+ do {
+ if (TagFile.Step(Section) == false)
+ {
+ strprintf(ErrorText, _("No sections in Release file %s"), Filename.c_str());
+ return false;
+ }
+
+ Section.Get (Start, End, 0);
+ } while (End - Start > 5 && strncmp(Start, "-----", 5) == 0);
Suite = Section.FindS("Suite");
Dist = Section.FindS("Codename");
diff --git a/apt-pkg/init.cc b/apt-pkg/init.cc
index e031cbb94..0354e6e4d 100644
--- a/apt-pkg/init.cc
+++ b/apt-pkg/init.cc
@@ -52,7 +52,7 @@ bool pkgInitConfig(Configuration &Cnf)
Cnf.Set("Dir::State::lists","lists/");
Cnf.Set("Dir::State::cdroms","cdroms.list");
Cnf.Set("Dir::State::mirrors","mirrors/");
-
+
// Cache
Cnf.Set("Dir::Cache","var/cache/apt/");
Cnf.Set("Dir::Cache::archives","archives/");
@@ -91,16 +91,19 @@ bool pkgInitConfig(Configuration &Cnf)
// Translation
Cnf.Set("APT::Acquire::Translation", "environment");
+ // Default cdrom mount point
+ Cnf.Set("Acquire::cdrom::mount", "/media/cdrom/");
+
bool Res = true;
// Read an alternate config file
const char *Cfg = getenv("APT_CONFIG");
if (Cfg != 0)
{
- if (FileExists(Cfg) == true)
+ if (RealFileExists(Cfg) == true)
Res &= ReadConfigFile(Cnf,Cfg);
else
- _error->WarningE("FileExists",_("Unable to read %s"),Cfg);
+ _error->WarningE("RealFileExists",_("Unable to read %s"),Cfg);
}
// Read the configuration parts dir
@@ -112,7 +115,7 @@ bool pkgInitConfig(Configuration &Cnf)
// Read the main config file
string FName = Cnf.FindFile("Dir::Etc::main");
- if (FileExists(FName) == true)
+ if (RealFileExists(FName) == true)
Res &= ReadConfigFile(Cnf,FName);
if (Res == false)
diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc
index ed35174bb..5b943cca1 100644
--- a/apt-pkg/pkgcachegen.cc
+++ b/apt-pkg/pkgcachegen.cc
@@ -638,21 +638,19 @@ bool pkgCacheGenerator::FinishCache(OpProgress *Progress)
Dynamic<pkgCache::PkgIterator> DynP(P);
for (; P.end() != true; P = G.NextPkg(P))
{
- if (strcmp(P.Arch(),"all") == 0)
- continue;
pkgCache::PkgIterator allPkg;
Dynamic<pkgCache::PkgIterator> DynallPkg(allPkg);
pkgCache::VerIterator V = P.VersionList();
Dynamic<pkgCache::VerIterator> DynV(V);
for (; V.end() != true; V++)
{
- string const Arch = V.Arch(true);
+ char const * const Arch = P.Arch();
map_ptrloc *OldDepLast = NULL;
/* MultiArch handling introduces a lot of implicit Dependencies:
- MultiArch: same → Co-Installable if they have the same version
- Architecture: all → Need to be Co-Installable for internal reasons
- All others conflict with all other group members */
- bool const coInstall = (V->MultiArch == pkgCache::Version::All ||
+ bool const coInstall = ((V->MultiArch == pkgCache::Version::All && strcmp(Arch, "all") != 0) ||
V->MultiArch == pkgCache::Version::Same);
if (V->MultiArch == pkgCache::Version::All && allPkg.end() == true)
allPkg = G.FindPkg("all");
@@ -686,9 +684,15 @@ bool pkgCacheGenerator::FinishCache(OpProgress *Progress)
}
} else {
// Conflicts: ${self}:other
- NewDepends(D, V, "",
- pkgCache::Dep::NoOp, pkgCache::Dep::Conflicts,
- OldDepLast);
+ if (strcmp(Arch, "all") == 0) {
+ NewDepends(D, V, V.VerStr(),
+ pkgCache::Dep::NotEquals, pkgCache::Dep::Conflicts,
+ OldDepLast);
+ } else {
+ NewDepends(D, V, "",
+ pkgCache::Dep::NoOp, pkgCache::Dep::Conflicts,
+ OldDepLast);
+ }
}
}
}
diff --git a/apt-pkg/policy.cc b/apt-pkg/policy.cc
index 4f9d56775..5427271b6 100644
--- a/apt-pkg/policy.cc
+++ b/apt-pkg/policy.cc
@@ -45,6 +45,8 @@ using namespace std;
file matches the V0 policy engine. */
pkgPolicy::pkgPolicy(pkgCache *Owner) : Pins(0), PFPriority(0), Cache(Owner)
{
+ if (Owner == 0 || &(Owner->Head()) == 0)
+ return;
PFPriority = new signed short[Owner->Head().PackageFileCount];
Pins = new Pin[Owner->Head().PackageCount];
@@ -328,7 +330,7 @@ bool ReadPinFile(pkgPolicy &Plcy,string File)
if (File.empty() == true)
File = _config->FindFile("Dir::Etc::Preferences");
- if (FileExists(File) == false)
+ if (RealFileExists(File) == false)
return true;
FileFd Fd(File,FileFd::ReadOnly);
diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc
index c3ec9865a..851eefdfe 100644
--- a/apt-pkg/sourcelist.cc
+++ b/apt-pkg/sourcelist.cc
@@ -197,7 +197,7 @@ bool pkgSourceList::ReadMainList()
string Main = _config->FindFile("Dir::Etc::sourcelist");
string Parts = _config->FindDir("Dir::Etc::sourceparts");
- if (FileExists(Main) == true)
+ if (RealFileExists(Main) == true)
Res &= ReadAppend(Main);
else if (DirectoryExists(Parts) == false)
// Only warn if there are no sources.list.d.
@@ -205,9 +205,9 @@ bool pkgSourceList::ReadMainList()
if (DirectoryExists(Parts) == true)
Res &= ReadSourceDir(Parts);
- else if (FileExists(Main) == false)
+ else if (RealFileExists(Main) == false)
// Only warn if there is no sources.list file.
- _error->WarningE("FileExists", _("Unable to read %s"), Main.c_str());
+ _error->WarningE("RealFileExists", _("Unable to read %s"), Main.c_str());
return Res;
}
diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc
index 96a681bec..4a2f3f7e6 100644
--- a/apt-pkg/tagfile.cc
+++ b/apt-pkg/tagfile.cc
@@ -399,9 +399,13 @@ bool pkgTagSection::FindFlag(const char *Tag,unsigned long &Flags,
const char *Stop;
if (Find(Tag,Start,Stop) == false)
return true;
-
- switch (StringToBool(string(Start,Stop)))
- {
+ return FindFlag(Flags, Flag, Start, Stop);
+}
+bool const pkgTagSection::FindFlag(unsigned long &Flags, unsigned long Flag,
+ char const* Start, char const* Stop)
+{
+ switch (StringToBool(string(Start, Stop)))
+ {
case 0:
Flags &= ~Flag;
return true;
diff --git a/apt-pkg/tagfile.h b/apt-pkg/tagfile.h
index 6891c1d81..61491aa04 100644
--- a/apt-pkg/tagfile.h
+++ b/apt-pkg/tagfile.h
@@ -60,6 +60,8 @@ class pkgTagSection
unsigned long long FindULL(const char *Tag, unsigned long long const &Default = 0) const;
bool FindFlag(const char *Tag,unsigned long &Flags,
unsigned long Flag) const;
+ bool static const FindFlag(unsigned long &Flags, unsigned long Flag,
+ const char* Start, const char* Stop);
bool Scan(const char *Start,unsigned long MaxLength);
inline unsigned long size() const {return Stop - Section;};
void Trim();
diff --git a/apt-pkg/vendorlist.cc b/apt-pkg/vendorlist.cc
index 589997081..92ff38894 100644
--- a/apt-pkg/vendorlist.cc
+++ b/apt-pkg/vendorlist.cc
@@ -21,11 +21,11 @@ bool pkgVendorList::ReadMainList()
Configuration Cnf;
string CnfFile = _config->FindDir("Dir::Etc::vendorparts");
- if (FileExists(CnfFile) == true)
+ if (DirectoryExists(CnfFile) == true)
if (ReadConfigDir(Cnf,CnfFile,true) == false)
return false;
CnfFile = _config->FindFile("Dir::Etc::vendorlist");
- if (FileExists(CnfFile) == true)
+ if (RealFileExists(CnfFile) == true)
if (ReadConfigFile(Cnf,CnfFile,true) == false)
return false;