summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
authorMichael Vogt <michael.vogt@ubuntu.com>2010-01-26 15:51:45 +0100
committerMichael Vogt <michael.vogt@ubuntu.com>2010-01-26 15:51:45 +0100
commit51f9f4d78deabf54dbbb6881139d2b1a319ffbfc (patch)
tree60a2bcd8911acd5c4ab8b4558bfd30344b673ff5 /apt-pkg
parent76fe5db7153957f8fda437e3bd614312b076f19e (diff)
parentc1f168f54be5b4babeb9b91cd7145441ea2489ad (diff)
merge from the mvo branch
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/acquire-item.cc167
-rw-r--r--apt-pkg/acquire-item.h54
-rw-r--r--apt-pkg/acquire-method.cc2
-rw-r--r--apt-pkg/acquire.cc7
-rw-r--r--apt-pkg/acquire.h26
-rw-r--r--apt-pkg/algorithms.cc110
-rw-r--r--apt-pkg/algorithms.h8
-rw-r--r--apt-pkg/aptconfiguration.cc90
-rw-r--r--apt-pkg/aptconfiguration.h46
-rw-r--r--apt-pkg/cachefile.cc9
-rw-r--r--apt-pkg/cacheiterators.h50
-rw-r--r--apt-pkg/cdrom.cc34
-rw-r--r--apt-pkg/cdrom.h16
-rw-r--r--apt-pkg/clean.cc1
-rw-r--r--apt-pkg/contrib/cdromutl.cc51
-rw-r--r--apt-pkg/contrib/configuration.cc32
-rw-r--r--apt-pkg/contrib/configuration.h3
-rw-r--r--apt-pkg/contrib/error.cc13
-rw-r--r--apt-pkg/contrib/fileutl.cc2
-rw-r--r--apt-pkg/contrib/hashes.cc24
-rw-r--r--apt-pkg/contrib/md5.cc13
-rw-r--r--apt-pkg/contrib/mmap.cc120
-rw-r--r--apt-pkg/contrib/mmap.h2
-rw-r--r--apt-pkg/contrib/netrc.cc211
-rw-r--r--apt-pkg/contrib/netrc.h29
-rw-r--r--apt-pkg/contrib/sha256.cc32
-rw-r--r--apt-pkg/contrib/strutl.cc30
-rw-r--r--apt-pkg/contrib/strutl.h14
-rw-r--r--apt-pkg/deb/deblistparser.cc4
-rw-r--r--apt-pkg/deb/debmetaindex.cc7
-rw-r--r--apt-pkg/deb/debmetaindex.h1
-rw-r--r--apt-pkg/deb/debsrcrecords.cc16
-rw-r--r--apt-pkg/deb/debsrcrecords.h1
-rw-r--r--apt-pkg/deb/debsystem.cc4
-rw-r--r--apt-pkg/deb/dpkgpm.cc308
-rw-r--r--apt-pkg/deb/dpkgpm.h7
-rw-r--r--apt-pkg/depcache.cc179
-rw-r--r--apt-pkg/depcache.h51
-rw-r--r--apt-pkg/indexcopy.cc25
-rw-r--r--apt-pkg/indexcopy.h22
-rw-r--r--apt-pkg/indexfile.cc1
-rw-r--r--apt-pkg/indexrecords.cc14
-rw-r--r--apt-pkg/init.cc22
-rw-r--r--apt-pkg/init.h8
-rw-r--r--apt-pkg/makefile22
-rw-r--r--apt-pkg/metaindex.h8
-rw-r--r--apt-pkg/orderlist.cc73
-rw-r--r--apt-pkg/packagemanager.cc68
-rw-r--r--apt-pkg/packagemanager.h2
-rw-r--r--apt-pkg/pkgcache.cc69
-rw-r--r--apt-pkg/pkgcache.h51
-rw-r--r--apt-pkg/pkgcachegen.cc42
-rw-r--r--apt-pkg/pkgcachegen.h8
-rw-r--r--apt-pkg/pkgrecords.h8
-rw-r--r--apt-pkg/policy.cc84
-rw-r--r--apt-pkg/policy.h1
-rw-r--r--apt-pkg/sourcelist.cc13
-rw-r--r--apt-pkg/tagfile.cc21
-rw-r--r--apt-pkg/tagfile.h5
-rw-r--r--apt-pkg/vendorlist.cc19
-rw-r--r--apt-pkg/versionmatch.cc37
-rw-r--r--apt-pkg/versionmatch.h21
62 files changed, 1711 insertions, 707 deletions
diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc
index 09ea5da02..afb3daad3 100644
--- a/apt-pkg/acquire-item.cc
+++ b/apt-pkg/acquire-item.cc
@@ -15,6 +15,7 @@
// Include Files /*{{{*/
#include <apt-pkg/acquire-item.h>
#include <apt-pkg/configuration.h>
+#include <apt-pkg/aptconfiguration.h>
#include <apt-pkg/sourcelist.h>
#include <apt-pkg/vendorlist.h>
#include <apt-pkg/error.h>
@@ -131,9 +132,7 @@ void pkgAcquire::Item::Rename(string From,string To)
}
}
/*}}}*/
-
-
-// AcqDiffIndex::AcqDiffIndex - Constructor
+// AcqDiffIndex::AcqDiffIndex - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* Get the DiffIndex file first and see if there are patches availabe
* If so, create a pkgAcqIndexDiffs fetcher that will get and apply the
@@ -184,7 +183,7 @@ pkgAcqDiffIndex::pkgAcqDiffIndex(pkgAcquire *Owner,
QueueURI(Desc);
}
-
+ /*}}}*/
// AcqIndex::Custom600Headers - Insert custom request headers /*{{{*/
// ---------------------------------------------------------------------
/* The only header we use is the last-modified header. */
@@ -202,9 +201,8 @@ string pkgAcqDiffIndex::Custom600Headers()
return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
}
-
-
-bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile)
+ /*}}}*/
+bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile) /*{{{*/
{
if(Debug)
std::clog << "pkgAcqIndexDiffs::ParseIndexDiff() " << IndexDiffFile
@@ -291,8 +289,8 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile)
std::clog << "Can't find a patch in the index file" << std::endl;
return false;
}
-
-void pkgAcqDiffIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
+ /*}}}*/
+void pkgAcqDiffIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*{{{*/
{
if(Debug)
std::clog << "pkgAcqDiffIndex failed: " << Desc.URI << std::endl
@@ -305,8 +303,8 @@ void pkgAcqDiffIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
Status = StatDone;
Dequeue();
}
-
-void pkgAcqDiffIndex::Done(string Message,unsigned long Size,string Md5Hash,
+ /*}}}*/
+void pkgAcqDiffIndex::Done(string Message,unsigned long Size,string Md5Hash, /*{{{*/
pkgAcquire::MethodConfig *Cnf)
{
if(Debug)
@@ -335,10 +333,8 @@ void pkgAcqDiffIndex::Done(string Message,unsigned long Size,string Md5Hash,
Dequeue();
return;
}
-
-
-
-// AcqIndexDiffs::AcqIndexDiffs - Constructor
+ /*}}}*/
+// AcqIndexDiffs::AcqIndexDiffs - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* The package diff is added to the queue. one object is constructed
* for each diff and the index
@@ -372,9 +368,8 @@ pkgAcqIndexDiffs::pkgAcqIndexDiffs(pkgAcquire *Owner,
QueueNextDiff();
}
}
-
-
-void pkgAcqIndexDiffs::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
+ /*}}}*/
+void pkgAcqIndexDiffs::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*{{{*/
{
if(Debug)
std::clog << "pkgAcqIndexDiffs failed: " << Desc.URI << std::endl
@@ -383,9 +378,8 @@ void pkgAcqIndexDiffs::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
ExpectedHash);
Finish();
}
-
-
-// helper that cleans the item out of the fetcher queue
+ /*}}}*/
+// Finish - helper that cleans the item out of the fetcher queue /*{{{*/
void pkgAcqIndexDiffs::Finish(bool allDone)
{
// we restore the original name, this is required, otherwise
@@ -420,10 +414,8 @@ void pkgAcqIndexDiffs::Finish(bool allDone)
Dequeue();
return;
}
-
-
-
-bool pkgAcqIndexDiffs::QueueNextDiff()
+ /*}}}*/
+bool pkgAcqIndexDiffs::QueueNextDiff() /*{{{*/
{
// calc sha1 of the just patched file
@@ -469,10 +461,8 @@ bool pkgAcqIndexDiffs::QueueNextDiff()
return true;
}
-
-
-
-void pkgAcqIndexDiffs::Done(string Message,unsigned long Size,string Md5Hash,
+ /*}}}*/
+void pkgAcqIndexDiffs::Done(string Message,unsigned long Size,string Md5Hash, /*{{{*/
pkgAcquire::MethodConfig *Cnf)
{
if(Debug)
@@ -543,8 +533,7 @@ void pkgAcqIndexDiffs::Done(string Message,unsigned long Size,string Md5Hash,
return Finish(true);
}
}
-
-
+ /*}}}*/
// AcqIndex::AcqIndex - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* The package file is added to the queue and a second class is
@@ -563,13 +552,14 @@ pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,
if(comprExt.empty())
{
// autoselect the compression method
- if(FileExists("/bin/bzip2"))
- CompressionExtension = ".bz2";
- else
- CompressionExtension = ".gz";
- } else {
- CompressionExtension = (comprExt == "plain" ? "" : comprExt);
+ 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;
Desc.Description = URIDesc;
@@ -594,27 +584,29 @@ string pkgAcqIndex::Custom600Headers()
return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
}
/*}}}*/
-
-void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
+void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*{{{*/
{
- bool descChanged = false;
- // no .bz2 found, retry with .gz
- if(Desc.URI.substr(Desc.URI.size()-3) == "bz2") {
- Desc.URI = Desc.URI.substr(0,Desc.URI.size()-3) + "gz";
-
- new pkgAcqIndex(Owner, RealURI, Desc.Description,Desc.ShortDesc,
- ExpectedHash, string(".gz"));
- descChanged = true;
- }
- // no .gz found, retry with uncompressed
- else if(Desc.URI.substr(Desc.URI.size()-2) == "gz") {
- Desc.URI = Desc.URI.substr(0,Desc.URI.size()-2);
+ std::vector<std::string> types = APT::Configuration::getCompressionTypes();
- new pkgAcqIndex(Owner, RealURI, Desc.Description,Desc.ShortDesc,
- ExpectedHash, string("plain"));
- descChanged = true;
- }
- if (descChanged) {
+ for (std::vector<std::string>::const_iterator t = types.begin();
+ t != types.end(); t++)
+ {
+ // 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();
@@ -630,8 +622,7 @@ void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
Item::Failed(Message,Cnf);
}
-
-
+ /*}}}*/
// AcqIndex::Done - Finished a fetch /*{{{*/
// ---------------------------------------------------------------------
/* This goes through a number of states.. On the initial fetch the
@@ -712,11 +703,11 @@ void pkgAcqIndex::Done(string Message,unsigned long Size,string Hash,
Local = true;
string compExt = flExtension(flNotDir(URI(Desc.URI).Path));
- const char *decompProg;
- if(compExt == "bz2")
- decompProg = "bzip2";
- else if(compExt == "gz")
- decompProg = "gzip";
+ string decompProg;
+
+ // 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
@@ -731,11 +722,11 @@ void pkgAcqIndex::Done(string Message,unsigned long Size,string Hash,
Decompression = true;
DestFile += ".decomp";
- Desc.URI = string(decompProg) + ":" + FileName;
+ Desc.URI = decompProg + ":" + FileName;
QueueURI(Desc);
- Mode = decompProg;
+ Mode = decompProg.c_str();
}
-
+ /*}}}*/
// AcqIndexTrans::pkgAcqIndexTrans - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* The Translation file is added to the queue */
@@ -744,7 +735,6 @@ pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcquire *Owner,
: pkgAcqIndex(Owner, URI, URIDesc, ShortDesc, HashString(), "")
{
}
-
/*}}}*/
// AcqIndexTrans::Failed - Silence failure messages for missing files /*{{{*/
// ---------------------------------------------------------------------
@@ -764,8 +754,7 @@ void pkgAcqIndexTrans::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
Item::Failed(Message,Cnf);
}
/*}}}*/
-
-pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire *Owner,
+pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire *Owner, /*{{{*/
string URI,string URIDesc,string ShortDesc,
string MetaIndexURI, string MetaIndexURIDesc,
string MetaIndexShortDesc,
@@ -854,7 +843,7 @@ void pkgAcqMetaSig::Done(string Message,unsigned long Size,string MD5,
}
/*}}}*/
-void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
+void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf)/*{{{*/
{
string Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
@@ -890,8 +879,8 @@ void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
Item::Failed(Message,Cnf);
}
-
-pkgAcqMetaIndex::pkgAcqMetaIndex(pkgAcquire *Owner,
+ /*}}}*/
+pkgAcqMetaIndex::pkgAcqMetaIndex(pkgAcquire *Owner, /*{{{*/
string URI,string URIDesc,string ShortDesc,
string SigFile,
const vector<struct IndexTarget*>* IndexTargets,
@@ -910,7 +899,6 @@ pkgAcqMetaIndex::pkgAcqMetaIndex(pkgAcquire *Owner,
QueueURI(Desc);
}
-
/*}}}*/
// pkgAcqMetaIndex::Custom600Headers - Insert custom request headers /*{{{*/
// ---------------------------------------------------------------------
@@ -926,8 +914,8 @@ string pkgAcqMetaIndex::Custom600Headers()
return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
}
-
-void pkgAcqMetaIndex::Done(string Message,unsigned long Size,string Hash,
+ /*}}}*/
+void pkgAcqMetaIndex::Done(string Message,unsigned long Size,string Hash, /*{{{*/
pkgAcquire::MethodConfig *Cfg)
{
Item::Done(Message,Size,Hash,Cfg);
@@ -968,8 +956,8 @@ void pkgAcqMetaIndex::Done(string Message,unsigned long Size,string Hash,
}
}
}
-
-void pkgAcqMetaIndex::RetrievalDone(string Message)
+ /*}}}*/
+void pkgAcqMetaIndex::RetrievalDone(string Message) /*{{{*/
{
// We have just finished downloading a Release file (it is not
// verified yet)
@@ -1007,8 +995,8 @@ void pkgAcqMetaIndex::RetrievalDone(string Message)
chmod(FinalFile.c_str(),0644);
DestFile = FinalFile;
}
-
-void pkgAcqMetaIndex::AuthDone(string Message)
+ /*}}}*/
+void pkgAcqMetaIndex::AuthDone(string Message) /*{{{*/
{
// At this point, the gpgv method has succeeded, so there is a
// valid signature from a key in the trusted keyring. We
@@ -1041,8 +1029,8 @@ void pkgAcqMetaIndex::AuthDone(string Message)
Rename(SigFile,VerifiedSigFile);
chmod(VerifiedSigFile.c_str(),0644);
}
-
-void pkgAcqMetaIndex::QueueIndexes(bool verify)
+ /*}}}*/
+void pkgAcqMetaIndex::QueueIndexes(bool verify) /*{{{*/
{
for (vector <struct IndexTarget*>::const_iterator Target = IndexTargets->begin();
Target != IndexTargets->end();
@@ -1084,8 +1072,8 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify)
(*Target)->ShortDesc, ExpectedIndexHash);
}
}
-
-bool pkgAcqMetaIndex::VerifyVendor(string Message)
+ /*}}}*/
+bool pkgAcqMetaIndex::VerifyVendor(string Message) /*{{{*/
{
// // Maybe this should be made available from above so we don't have
// // to read and parse it every time?
@@ -1171,9 +1159,8 @@ bool pkgAcqMetaIndex::VerifyVendor(string Message)
return true;
}
- /*}}}*/
-// pkgAcqMetaIndex::Failed - no Release file present or no signature
-// file present /*{{{*/
+ /*}}}*/
+// pkgAcqMetaIndex::Failed - no Release file present or no signature file present /*{{{*/
// ---------------------------------------------------------------------
/* */
void pkgAcqMetaIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
@@ -1210,9 +1197,7 @@ void pkgAcqMetaIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
// back to queueing Packages files without verification
QueueIndexes(false);
}
-
/*}}}*/
-
// AcqArchive::AcqArchive - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* This just sets up the initial fetch environment and queues the first
@@ -1495,14 +1480,13 @@ void pkgAcqArchive::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
}
}
/*}}}*/
-// AcqArchive::IsTrusted - Determine whether this archive comes from a
-// trusted source /*{{{*/
+// AcqArchive::IsTrusted - Determine whether this archive comes from a trusted source /*{{{*/
// ---------------------------------------------------------------------
bool pkgAcqArchive::IsTrusted()
{
return Trusted;
}
-
+ /*}}}*/
// AcqArchive::Finished - Fetching has finished, tidy up /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -1514,7 +1498,6 @@ void pkgAcqArchive::Finished()
StoreFilename = string();
}
/*}}}*/
-
// AcqFile::pkgAcqFile - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* The file is added to the queue */
diff --git a/apt-pkg/acquire-item.h b/apt-pkg/acquire-item.h
index a48f7f7e5..3f073de5b 100644
--- a/apt-pkg/acquire-item.h
+++ b/apt-pkg/acquire-item.h
@@ -34,7 +34,7 @@
* \file acquire-item.h
*/
-/** \brief Represents the process by which a pkgAcquire object should
+/** \brief Represents the process by which a pkgAcquire object should {{{
* retrieve a file or a collection of files.
*
* By convention, Item subclasses should insert themselves into the
@@ -261,8 +261,8 @@ class pkgAcquire::Item
*/
virtual ~Item();
};
-
-/** \brief Information about an index patch (aka diff). */
+ /*}}}*/
+/** \brief Information about an index patch (aka diff). */ /*{{{*/
struct DiffInfo {
/** The filename of the diff. */
string file;
@@ -273,8 +273,8 @@ struct DiffInfo {
/** The size of the diff. */
unsigned long size;
};
-
-/** \brief An item that is responsible for fetching an index file of
+ /*}}}*/
+/** \brief An item that is responsible for fetching an index file of {{{
* package list diffs and starting the package list's download.
*
* This item downloads the Index file and parses it, then enqueues
@@ -348,8 +348,8 @@ class pkgAcqDiffIndex : public pkgAcquire::Item
pkgAcqDiffIndex(pkgAcquire *Owner,string URI,string URIDesc,
string ShortDesc, HashString ExpectedHash);
};
-
-/** \brief An item that is responsible for fetching all the patches
+ /*}}}*/
+/** \brief An item that is responsible for fetching all the patches {{{
* that need to be applied to a given package index file.
*
* After downloading and applying a single patch, this item will
@@ -477,8 +477,8 @@ class pkgAcqIndexDiffs : public pkgAcquire::Item
string ShortDesc, HashString ExpectedHash,
vector<DiffInfo> diffs=vector<DiffInfo>());
};
-
-/** \brief An acquire item that is responsible for fetching an index
+ /*}}}*/
+/** \brief An acquire item that is responsible for fetching an index {{{
* file (e.g., Packages or Sources).
*
* \sa pkgAcqDiffIndex, pkgAcqIndexDiffs, pkgAcqIndexTrans
@@ -540,13 +540,15 @@ class pkgAcqIndex : public pkgAcquire::Item
*
* \param compressExt The compression-related extension with which
* this index file should be downloaded, or "" to autodetect
- * (".bz2" is used if bzip2 is installed, ".gz" otherwise).
+ * Compression types can be set with config Acquire::CompressionTypes,
+ * default is ".lzma" or ".bz2" (if the needed binaries are present)
+ * fallback is ".gz" or none.
*/
pkgAcqIndex(pkgAcquire *Owner,string URI,string URIDesc,
string ShortDesc, HashString ExpectedHash, string compressExt="");
};
-
-/** \brief An acquire item that is responsible for fetching a
+ /*}}}*/
+/** \brief An acquire item that is responsible for fetching a {{{
* translated index file.
*
* The only difference from pkgAcqIndex is that transient failures
@@ -569,18 +571,12 @@ class pkgAcqIndexTrans : public pkgAcqIndex
* \param URIDesc A "URI-style" description of this index file.
*
* \param ShortDesc A brief description of this index file.
- *
- * \param ExpectedHash The expected hashsum of this index file.
- *
- * \param compressExt The compression-related extension with which
- * this index file should be downloaded, or "" to autodetect
- * (".bz2" is used if bzip2 is installed, ".gz" otherwise).
*/
pkgAcqIndexTrans(pkgAcquire *Owner,string URI,string URIDesc,
string ShortDesc);
};
-
-/** \brief Information about an index file. */
+ /*}}}*/
+/** \brief Information about an index file. */ /*{{{*/
struct IndexTarget
{
/** \brief A URI from which the index file can be downloaded. */
@@ -597,8 +593,8 @@ struct IndexTarget
*/
string MetaKey;
};
-
-/** \brief An acquire item that downloads the detached signature
+ /*}}}*/
+/** \brief An acquire item that downloads the detached signature {{{
* of a meta-index (Release) file, then queues up the release
* file itself.
*
@@ -660,8 +656,8 @@ class pkgAcqMetaSig : public pkgAcquire::Item
const vector<struct IndexTarget*>* IndexTargets,
indexRecords* MetaIndexParser);
};
-
-/** \brief An item that is responsible for downloading the meta-index
+ /*}}}*/
+/** \brief An item that is responsible for downloading the meta-index {{{
* file (i.e., Release) itself and verifying its signature.
*
* Once the download and verification are complete, the downloads of
@@ -756,8 +752,8 @@ class pkgAcqMetaIndex : public pkgAcquire::Item
const vector<struct IndexTarget*>* IndexTargets,
indexRecords* MetaIndexParser);
};
-
-/** \brief An item that is responsible for fetching a package file.
+ /*}}}*/
+/** \brief An item that is responsible for fetching a package file. {{{
*
* If the package file already exists in the cache, nothing will be
* done.
@@ -840,8 +836,8 @@ class pkgAcqArchive : public pkgAcquire::Item
pkgRecords *Recs,pkgCache::VerIterator const &Version,
string &StoreFilename);
};
-
-/** \brief Retrieve an arbitrary file to the current directory.
+ /*}}}*/
+/** \brief Retrieve an arbitrary file to the current directory. {{{
*
* The file is retrieved even if it is accessed via a URL type that
* normally is a NOP, such as "file". If the download fails, the
@@ -902,7 +898,7 @@ class pkgAcqFile : public pkgAcquire::Item
string Desc, string ShortDesc,
const string &DestDir="", const string &DestFilename="");
};
-
+ /*}}}*/
/** @} */
#endif
diff --git a/apt-pkg/acquire-method.cc b/apt-pkg/acquire-method.cc
index acf1156dc..fe066741c 100644
--- a/apt-pkg/acquire-method.cc
+++ b/apt-pkg/acquire-method.cc
@@ -446,7 +446,6 @@ void pkgAcqMethod::Status(const char *Format,...)
exit(100);
}
/*}}}*/
-
// AcqMethod::Redirect - Send a redirect message /*{{{*/
// ---------------------------------------------------------------------
/* This method sends the redirect message and also manipulates the queue
@@ -478,7 +477,6 @@ void pkgAcqMethod::Redirect(const string &NewURI)
QueueBack = I->Next;
}
/*}}}*/
-
// AcqMethod::FetchResult::FetchResult - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
diff --git a/apt-pkg/acquire.cc b/apt-pkg/acquire.cc
index bafba337e..74510ae21 100644
--- a/apt-pkg/acquire.cc
+++ b/apt-pkg/acquire.cc
@@ -266,7 +266,7 @@ pkgAcquire::MethodConfig *pkgAcquire::GetConfig(string Access)
return 0;
/* if a method uses DownloadLimit, we switch to SingleInstance mode */
- if(_config->FindI("Acquire::"+Access+"::DlLimit",0) > 0)
+ if(_config->FindI("Acquire::"+Access+"::Dl-Limit",0) > 0)
Conf->SingleInstance = true;
return Conf;
@@ -485,7 +485,7 @@ double pkgAcquire::PartialPresent()
Total += (*I)->PartialSize;
return Total;
}
-
+ /*}}}*/
// Acquire::UriBegin - Start iterator for the uri list /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -502,7 +502,6 @@ pkgAcquire::UriIterator pkgAcquire::UriEnd()
return UriIterator(0);
}
/*}}}*/
-
// Acquire::MethodConfig::MethodConfig - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -516,7 +515,6 @@ pkgAcquire::MethodConfig::MethodConfig()
Next = 0;
}
/*}}}*/
-
// Queue::Queue - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -728,7 +726,6 @@ void pkgAcquire::Queue::Bump()
Cycle();
}
/*}}}*/
-
// AcquireStatus::pkgAcquireStatus - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
diff --git a/apt-pkg/acquire.h b/apt-pkg/acquire.h
index 1de6f5e44..6c130c1b3 100644
--- a/apt-pkg/acquire.h
+++ b/apt-pkg/acquire.h
@@ -30,7 +30,7 @@
##################################################################### */
/*}}}*/
-/** \defgroup acquire Acquire system
+/** \defgroup acquire Acquire system {{{
*
* \brief The Acquire system is responsible for retrieving files from
* local or remote URIs and postprocessing them (for instance,
@@ -54,7 +54,7 @@
* once, but it is not clear what its behavior in this case is, and
* no subclass of pkgAcquire::Item seems to actually use this
* capability.
- */
+ */ /*}}}*/
/** \addtogroup acquire
*
@@ -78,7 +78,7 @@ using std::string;
class pkgAcquireStatus;
-/** \brief The core download scheduler.
+/** \brief The core download scheduler. {{{
*
* This class represents an ongoing download. It manages the lists
* of active and pending downloads and handles setting up and tearing
@@ -366,8 +366,8 @@ struct pkgAcquire::ItemDesc
/** brief The underlying item which is to be downloaded. */
Item *Owner;
};
-
-/** \brief A single download queue in a pkgAcquire object.
+ /*}}}*/
+/** \brief A single download queue in a pkgAcquire object. {{{
*
* \todo Why so many protected values?
*/
@@ -528,8 +528,8 @@ class pkgAcquire::Queue
*/
~Queue();
};
-
-/** \brief Iterates over all the URIs being fetched by a pkgAcquire object. */
+ /*}}}*/
+/** \brief Iterates over all the URIs being fetched by a pkgAcquire object. {{{*/
class pkgAcquire::UriIterator
{
/** The next queue to iterate over. */
@@ -539,7 +539,7 @@ class pkgAcquire::UriIterator
public:
- inline void operator ++() {operator ++();};
+ inline void operator ++() {operator ++(0);};
void operator ++(int)
{
@@ -568,8 +568,8 @@ class pkgAcquire::UriIterator
}
}
};
-
-/** \brief Information about the properties of a single acquire method. */
+ /*}}}*/
+/** \brief Information about the properties of a single acquire method. {{{*/
struct pkgAcquire::MethodConfig
{
/** \brief The next link on the acquire method list.
@@ -621,8 +621,8 @@ struct pkgAcquire::MethodConfig
*/
MethodConfig();
};
-
-/** \brief A monitor object for downloads controlled by the pkgAcquire class.
+ /*}}}*/
+/** \brief A monitor object for downloads controlled by the pkgAcquire class. {{{
*
* \todo Why protected members?
*
@@ -762,7 +762,7 @@ class pkgAcquireStatus
pkgAcquireStatus();
virtual ~pkgAcquireStatus() {};
};
-
+ /*}}}*/
/** @} */
#endif
diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc
index b6f4705f3..34da745de 100644
--- a/apt-pkg/algorithms.cc
+++ b/apt-pkg/algorithms.cc
@@ -442,7 +442,6 @@ bool pkgMinimizeUpgrade(pkgDepCache &Cache)
return true;
}
/*}}}*/
-
// ProblemResolver::pkgProblemResolver - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -489,6 +488,36 @@ void pkgProblemResolver::MakeScores()
unsigned long Size = Cache.Head().PackageCount;
memset(Scores,0,sizeof(*Scores)*Size);
+ // Important Required Standard Optional Extra
+ signed short PrioMap[] = {
+ 0,
+ _config->FindI("pkgProblemResolver::Scores::Important",3),
+ _config->FindI("pkgProblemResolver::Scores::Required",2),
+ _config->FindI("pkgProblemResolver::Scores::Standard",1),
+ _config->FindI("pkgProblemResolver::Scores::Optional",-1),
+ _config->FindI("pkgProblemResolver::Scores::Extra",-2)
+ };
+ signed short PrioEssentials = _config->FindI("pkgProblemResolver::Scores::Essentials",100);
+ signed short PrioInstalledAndNotObsolete = _config->FindI("pkgProblemResolver::Scores::NotObsolete",1);
+ signed short PrioDepends = _config->FindI("pkgProblemResolver::Scores::Depends",1);
+ signed short PrioRecommends = _config->FindI("pkgProblemResolver::Scores::Recommends",1);
+ signed short AddProtected = _config->FindI("pkgProblemResolver::Scores::AddProtected",10000);
+ signed short AddEssential = _config->FindI("pkgProblemResolver::Scores::AddEssential",5000);
+
+ if (_config->FindB("Debug::pkgProblemResolver::ShowScores",false) == true)
+ clog << "Settings used to calculate pkgProblemResolver::Scores::" << endl
+ << " Important => " << PrioMap[1] << endl
+ << " Required => " << PrioMap[2] << endl
+ << " Standard => " << PrioMap[3] << endl
+ << " Optional => " << PrioMap[4] << endl
+ << " Extra => " << PrioMap[5] << endl
+ << " Essentials => " << PrioEssentials << endl
+ << " InstalledAndNotObsolete => " << PrioInstalledAndNotObsolete << endl
+ << " Depends => " << PrioDepends << endl
+ << " Recommends => " << PrioRecommends << endl
+ << " AddProtected => " << AddProtected << endl
+ << " AddEssential => " << AddEssential << endl;
+
// Generate the base scores for a package based on its properties
for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
{
@@ -502,11 +531,9 @@ void pkgProblemResolver::MakeScores()
to allow an obsolete essential packages to be removed by
a conflicts on a powerfull normal package (ie libc6) */
if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
- Score += 100;
+ Score += PrioEssentials;
// We transform the priority
- // Important Required Standard Optional Extra
- signed short PrioMap[] = {0,3,2,1,-1,-2};
if (Cache[I].InstVerIter(Cache)->Priority <= 5)
Score += PrioMap[Cache[I].InstVerIter(Cache)->Priority];
@@ -515,7 +542,7 @@ void pkgProblemResolver::MakeScores()
if those are not obsolete
*/
if (I->CurrentVer != 0 && Cache[I].CandidateVer != 0 && Cache[I].CandidateVerIter(Cache).Downloadable())
- Score += 1;
+ Score += PrioInstalledAndNotObsolete;
}
// Now that we have the base scores we go and propogate dependencies
@@ -527,9 +554,10 @@ void pkgProblemResolver::MakeScores()
for (pkgCache::DepIterator D = Cache[I].InstVerIter(Cache).DependsList(); D.end() == false; D++)
{
if (D->Type == pkgCache::Dep::Depends ||
- D->Type == pkgCache::Dep::PreDepends ||
- D->Type == pkgCache::Dep::Recommends)
- Scores[D.TargetPkg()->ID]++;
+ D->Type == pkgCache::Dep::PreDepends)
+ Scores[D.TargetPkg()->ID] += PrioDepends;
+ else if (D->Type == pkgCache::Dep::Recommends)
+ Scores[D.TargetPkg()->ID] += PrioRecommends;
}
}
@@ -576,10 +604,10 @@ void pkgProblemResolver::MakeScores()
for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
{
if ((Flags[I->ID] & Protected) != 0)
- Scores[I->ID] += 10000;
+ Scores[I->ID] += AddProtected;
if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
- Scores[I->ID] += 5000;
- }
+ Scores[I->ID] += AddEssential;
+ }
}
/*}}}*/
// ProblemResolver::DoUpgrade - Attempt to upgrade this package /*{{{*/
@@ -755,19 +783,21 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
*PEnd++ = I;
This = this;
qsort(PList,PEnd - PList,sizeof(*PList),&ScoreSort);
-
-/* for (pkgCache::Package **K = PList; K != PEnd; K++)
- if (Scores[(*K)->ID] != 0)
- {
- pkgCache::PkgIterator Pkg(Cache,*K);
- clog << Scores[(*K)->ID] << ' ' << Pkg.Name() <<
- ' ' << (pkgCache::Version *)Pkg.CurrentVer() << ' ' <<
- Cache[Pkg].InstallVer << ' ' << Cache[Pkg].CandidateVer << endl;
- } */
+
+ if (_config->FindB("Debug::pkgProblemResolver::ShowScores",false) == true)
+ {
+ clog << "Show Scores" << endl;
+ for (pkgCache::Package **K = PList; K != PEnd; K++)
+ if (Scores[(*K)->ID] != 0)
+ {
+ pkgCache::PkgIterator Pkg(Cache,*K);
+ clog << Scores[(*K)->ID] << ' ' << Pkg << std::endl;
+ }
+ }
if (Debug == true)
clog << "Starting 2" << endl;
-
+
/* Now consider all broken packages. For each broken package we either
remove the package or fix it's problem. We do this once, it should
not be possible for a loop to form (that is a < b < c and fixing b by
@@ -882,7 +912,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
}
if (Debug == true)
- clog << "Package " << I.Name() << " has broken dep on " << Start.TargetPkg().Name() << endl;
+ clog << "Package " << I.Name() << " has broken " << Start.DepType() << " on " << Start.TargetPkg().Name() << endl;
/* Look across the version list. If there are no possible
targets then we keep the package and bail. This is necessary
@@ -964,12 +994,9 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
if (Debug == true)
clog << " Removing " << I.Name() << " rather than change " << Start.TargetPkg().Name() << endl;
Cache.MarkDelete(I);
- if (Counter > 1)
- {
- if (Scores[Pkg->ID] > Scores[I->ID])
- Scores[I->ID] = Scores[Pkg->ID];
- }
- }
+ if (Counter > 1 && Scores[Pkg->ID] > Scores[I->ID])
+ Scores[I->ID] = Scores[Pkg->ID];
+ }
}
}
@@ -1141,9 +1168,6 @@ bool pkgProblemResolver::ResolveByKeep()
unsigned long Size = Cache.Head().PackageCount;
- if (Debug == true)
- clog << "Entering ResolveByKeep" << endl;
-
MakeScores();
/* We have to order the packages so that the broken fixing pass
@@ -1156,7 +1180,21 @@ bool pkgProblemResolver::ResolveByKeep()
*PEnd++ = I;
This = this;
qsort(PList,PEnd - PList,sizeof(*PList),&ScoreSort);
-
+
+ if (_config->FindB("Debug::pkgProblemResolver::ShowScores",false) == true)
+ {
+ clog << "Show Scores" << endl;
+ for (pkgCache::Package **K = PList; K != PEnd; K++)
+ if (Scores[(*K)->ID] != 0)
+ {
+ pkgCache::PkgIterator Pkg(Cache,*K);
+ clog << Scores[(*K)->ID] << ' ' << Pkg << std::endl;
+ }
+ }
+
+ if (Debug == true)
+ clog << "Entering ResolveByKeep" << endl;
+
// Consider each broken package
pkgCache::Package **LastStop = 0;
for (pkgCache::Package **K = PList; K != PEnd; K++)
@@ -1202,8 +1240,8 @@ bool pkgProblemResolver::ResolveByKeep()
while (true)
{
if (Debug == true)
- clog << "Package " << I.Name() << " has broken dep on " << Start.TargetPkg().Name() << endl;
-
+ clog << "Package " << I.Name() << " has broken " << Start.DepType() << " on " << Start.TargetPkg().Name() << endl;
+
// Look at all the possible provides on this package
SPtrArray<pkgCache::Version *> VList = Start.AllTargets();
for (pkgCache::Version **V = VList; *V != 0; V++)
@@ -1219,7 +1257,7 @@ bool pkgProblemResolver::ResolveByKeep()
if ((Flags[I->ID] & Protected) == 0)
{
if (Debug == true)
- clog << " Keeping Package " << Pkg.Name() << " due to dep" << endl;
+ clog << " Keeping Package " << Pkg.Name() << " due to " << Start.DepType() << endl;
Cache.MarkKeep(Pkg, false, false);
}
@@ -1276,7 +1314,6 @@ void pkgProblemResolver::InstallProtect()
}
}
/*}}}*/
-
// PrioSortList - Sort a list of versions by priority /*{{{*/
// ---------------------------------------------------------------------
/* This is ment to be used in conjunction with AllTargets to get a list
@@ -1307,7 +1344,6 @@ void pkgPrioSortList(pkgCache &Cache,pkgCache::Version **List)
qsort(List,Count,sizeof(*List),PrioComp);
}
/*}}}*/
-
// CacheFile::ListUpdate - update the cache files /*{{{*/
// ---------------------------------------------------------------------
/* This is a simple wrapper to update the cache. it will fetch stuff
diff --git a/apt-pkg/algorithms.h b/apt-pkg/algorithms.h
index d183cd213..cee30b679 100644
--- a/apt-pkg/algorithms.h
+++ b/apt-pkg/algorithms.h
@@ -39,7 +39,7 @@
using std::ostream;
-class pkgSimulate : public pkgPackageManager
+class pkgSimulate : public pkgPackageManager /*{{{*/
{
protected:
@@ -75,8 +75,8 @@ private:
pkgSimulate(pkgDepCache *Cache);
};
-
-class pkgProblemResolver
+ /*}}}*/
+class pkgProblemResolver /*{{{*/
{
pkgDepCache &Cache;
typedef pkgCache::PkgIterator PkgIterator;
@@ -124,7 +124,7 @@ class pkgProblemResolver
pkgProblemResolver(pkgDepCache *Cache);
~pkgProblemResolver();
};
-
+ /*}}}*/
bool pkgDistUpgrade(pkgDepCache &Cache);
bool pkgApplyStatus(pkgDepCache &Cache);
bool pkgFixBroken(pkgDepCache &Cache);
diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc
new file mode 100644
index 000000000..45ae9bed5
--- /dev/null
+++ b/apt-pkg/aptconfiguration.cc
@@ -0,0 +1,90 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+/* ######################################################################
+
+ Provide access methods to various configuration settings,
+ setup defaults and returns validate settings.
+
+ ##################################################################### */
+ /*}}}*/
+// Include Files /*{{{*/
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/aptconfiguration.h>
+#include <apt-pkg/configuration.h>
+
+#include <vector>
+#include <string>
+#include <algorithm>
+ /*}}}*/
+namespace APT {
+// getCompressionTypes - Return Vector of usbale compressiontypes /*{{{*/
+// ---------------------------------------------------------------------
+/* return a vector of compression types in the prefered order. */
+std::vector<std::string>
+const Configuration::getCompressionTypes(bool const &Cached) {
+ static std::vector<std::string> types;
+ if (types.empty() == false) {
+ if (Cached == true)
+ return types;
+ else
+ types.clear();
+ }
+
+ // setup the defaults for the compressiontypes => method mapping
+ _config->CndSet("Acquire::CompressionTypes::bz2","bzip2");
+ _config->CndSet("Acquire::CompressionTypes::lzma","lzma");
+ _config->CndSet("Acquire::CompressionTypes::gz","gzip");
+
+ // Set default application paths to check for optional compression types
+ _config->CndSet("Dir::Bin::lzma", "/usr/bin/lzma");
+ _config->CndSet("Dir::Bin::bzip2", "/bin/bzip2");
+
+ // accept non-list order as override setting for config settings on commandline
+ std::string const overrideOrder = _config->Find("Acquire::CompressionTypes::Order","");
+ if (overrideOrder.empty() == false)
+ types.push_back(overrideOrder);
+
+ // load the order setting into our vector
+ std::vector<std::string> const order = _config->FindVector("Acquire::CompressionTypes::Order");
+ for (std::vector<std::string>::const_iterator o = order.begin();
+ o != order.end(); o++) {
+ if ((*o).empty() == true)
+ continue;
+ // ignore types we have no method ready to use
+ if (_config->Exists(string("Acquire::CompressionTypes::").append(*o)) == false)
+ continue;
+ // ignore types we have no app ready to use
+ string const appsetting = string("Dir::Bin::").append(*o);
+ if (_config->Exists(appsetting) == true) {
+ std::string const app = _config->FindFile(appsetting.c_str(), "");
+ if (app.empty() == false && FileExists(app) == false)
+ continue;
+ }
+ types.push_back(*o);
+ }
+
+ // move again over the option tree to add all missing compression types
+ ::Configuration::Item const *Types = _config->Tree("Acquire::CompressionTypes");
+ if (Types != 0)
+ Types = Types->Child;
+
+ for (; Types != 0; Types = Types->Next) {
+ if (Types->Tag == "Order" || Types->Tag.empty() == true)
+ continue;
+ // ignore types we already have in the vector
+ if (std::find(types.begin(),types.end(),Types->Tag) != types.end())
+ continue;
+ // ignore types we have no app ready to use
+ string const appsetting = string("Dir::Bin::").append(Types->Value);
+ if (appsetting.empty() == false && _config->Exists(appsetting) == true) {
+ std::string const app = _config->FindFile(appsetting.c_str(), "");
+ if (app.empty() == false && FileExists(app) == false)
+ continue;
+ }
+ types.push_back(Types->Tag);
+ }
+
+ return types;
+}
+ /*}}}*/
+}
diff --git a/apt-pkg/aptconfiguration.h b/apt-pkg/aptconfiguration.h
new file mode 100644
index 000000000..6a123adce
--- /dev/null
+++ b/apt-pkg/aptconfiguration.h
@@ -0,0 +1,46 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+/** \class APT::Configuration
+ * \brief Provide access methods to various configuration settings
+ *
+ * This class and their methods providing a layer around the usual access
+ * methods with _config to ensure that settings are correct and to be able
+ * to set defaults without the need to recheck it in every method again.
+ */
+ /*}}}*/
+#ifndef APT_CONFIGURATION_H
+#define APT_CONFIGURATION_H
+// Include Files /*{{{*/
+#include <string>
+#include <vector>
+ /*}}}*/
+namespace APT {
+class Configuration { /*{{{*/
+public: /*{{{*/
+ /** \brief Returns a vector of usable Compression Types
+ *
+ * Files can be compressed in various ways to decrease the size of the
+ * download. Therefore the Acquiremethods support a few compression types
+ * and some archives provide also a few different types. This option
+ * group exists to give the user the choice to prefer one type over the
+ * other (some compression types are very resource intensive - great if you
+ * have a limited download, bad if you have a really lowpowered hardware.)
+ *
+ * This method ensures that the defaults are set and checks at runtime
+ * if the type can be used. E.g. the current default is to prefer bzip2
+ * over lzma and gz - if the bzip2 binary is not available it has not much
+ * sense in downloading the bz2 file, therefore we will not return bz2 as
+ * a usable compression type. The availability is checked with the settings
+ * in the Dir::Bin group.
+ *
+ * \param Cached saves the result so we need to calculated it only once
+ * this parameter should ony be used for testing purposes.
+ *
+ * \return a vector of (all) Language Codes in the prefered usage order
+ */
+ std::vector<std::string> static const getCompressionTypes(bool const &Cached = true);
+ /*}}}*/
+};
+ /*}}}*/
+}
+#endif
diff --git a/apt-pkg/cachefile.cc b/apt-pkg/cachefile.cc
index 1a84aea54..790312dc8 100644
--- a/apt-pkg/cachefile.cc
+++ b/apt-pkg/cachefile.cc
@@ -24,7 +24,6 @@
#include <apti18n.h>
/*}}}*/
-
// CacheFile::CacheFile - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -49,6 +48,7 @@ pkgCacheFile::~pkgCacheFile()
/* */
bool pkgCacheFile::BuildCaches(OpProgress &Progress,bool WithLock)
{
+ const bool ErrorWasEmpty = _error->empty();
if (WithLock == true)
if (_system->Lock() == false)
return false;
@@ -71,7 +71,7 @@ bool pkgCacheFile::BuildCaches(OpProgress &Progress,bool WithLock)
return _error->Error(_("The package lists or status file could not be parsed or opened."));
/* This sux, remove it someday */
- if (_error->empty() == false)
+ if (ErrorWasEmpty == true && _error->empty() == false)
_error->Warning(_("You may want to run apt-get update to correct these problems"));
Cache = new pkgCache(Map);
@@ -92,7 +92,8 @@ bool pkgCacheFile::Open(OpProgress &Progress,bool WithLock)
Policy = new pkgPolicy(Cache);
if (_error->PendingError() == true)
return false;
- if (ReadPinFile(*Policy) == false)
+
+ if (ReadPinFile(*Policy) == false || ReadPinDir(*Policy) == false)
return false;
// Create the dependency cache
@@ -108,8 +109,6 @@ bool pkgCacheFile::Open(OpProgress &Progress,bool WithLock)
return true;
}
/*}}}*/
-
-
// CacheFile::Close - close the cache files /*{{{*/
// ---------------------------------------------------------------------
/* */
diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h
index bbbcb7753..28466cd40 100644
--- a/apt-pkg/cacheiterators.h
+++ b/apt-pkg/cacheiterators.h
@@ -32,7 +32,7 @@
#define PKGLIB_CACHEITERATORS_H
-// Package Iterator
+// Package Iterator /*{{{*/
class pkgCache::PkgIterator
{
friend class pkgCache;
@@ -80,7 +80,13 @@ class pkgCache::PkgIterator
inline PrvIterator ProvidesList() const;
inline unsigned long Index() const {return Pkg - Owner->PkgP;};
OkState State() const;
-
+
+ //Nice printable representation
+ friend std::ostream& operator<<(std::ostream& out, pkgCache::PkgIterator Pkg);
+
+ const char *CandVersion() const;
+ const char *CurVersion() const;
+
// Constructors
inline PkgIterator(pkgCache &Owner,Package *Trg) : Pkg(Trg), Owner(&Owner),
HashIndex(0)
@@ -90,8 +96,8 @@ class pkgCache::PkgIterator
};
inline PkgIterator() : Pkg(0), Owner(0), HashIndex(0) {};
};
-
-// Version Iterator
+ /*}}}*/
+// Version Iterator /*{{{*/
class pkgCache::VerIterator
{
Version *Ver;
@@ -111,7 +117,10 @@ class pkgCache::VerIterator
inline bool operator ==(const VerIterator &B) const {return Ver == B.Ver;};
inline bool operator !=(const VerIterator &B) const {return Ver != B.Ver;};
int CompareVer(const VerIterator &B) const;
-
+
+ // Testing
+ inline bool IsGood() const { return Ver && Owner && ! end();};
+
// Accessors
inline Version *operator ->() {return Ver;};
inline Version const *operator ->() const {return Ver;};
@@ -146,8 +155,8 @@ class pkgCache::VerIterator
Ver = Owner.VerP;
};
};
-
-// Description Iterator
+ /*}}}*/
+// Description Iterator /*{{{*/
class pkgCache::DescIterator
{
Description *Desc;
@@ -190,8 +199,8 @@ class pkgCache::DescIterator
Desc = Owner.DescP;
};
};
-
-// Dependency iterator
+ /*}}}*/
+// Dependency iterator /*{{{*/
class pkgCache::DepIterator
{
Dependency *Dep;
@@ -249,8 +258,8 @@ class pkgCache::DepIterator
};
inline DepIterator() : Dep(0), Type(DepVer), Owner(0) {};
};
-
-// Provides iterator
+ /*}}}*/
+// Provides iterator /*{{{*/
class pkgCache::PrvIterator
{
Provides *Prv;
@@ -302,8 +311,8 @@ class pkgCache::PrvIterator
Prv = Owner.ProvideP;
};
};
-
-// Package file
+ /*}}}*/
+// Package file /*{{{*/
class pkgCache::PkgFileIterator
{
pkgCache *Owner;
@@ -333,6 +342,7 @@ class pkgCache::PkgFileIterator
inline const char *Component() const {return File->Component == 0?0:Owner->StrP + File->Component;};
inline const char *Version() const {return File->Version == 0?0:Owner->StrP + File->Version;};
inline const char *Origin() const {return File->Origin == 0?0:Owner->StrP + File->Origin;};
+ inline const char *Codename() const {return File->Codename ==0?0:Owner->StrP + File->Codename;};
inline const char *Label() const {return File->Label == 0?0:Owner->StrP + File->Label;};
inline const char *Site() const {return File->Site == 0?0:Owner->StrP + File->Site;};
inline const char *Architecture() const {return File->Architecture == 0?0:Owner->StrP + File->Architecture;};
@@ -348,8 +358,8 @@ class pkgCache::PkgFileIterator
inline PkgFileIterator(pkgCache &Owner) : Owner(&Owner), File(Owner.PkgFileP) {};
inline PkgFileIterator(pkgCache &Owner,PackageFile *Trg) : Owner(&Owner), File(Trg) {};
};
-
-// Version File
+ /*}}}*/
+// Version File /*{{{*/
class pkgCache::VerFileIterator
{
pkgCache *Owner;
@@ -380,8 +390,8 @@ class pkgCache::VerFileIterator
inline VerFileIterator() : Owner(0), FileP(0) {};
inline VerFileIterator(pkgCache &Owner,VerFile *Trg) : Owner(&Owner), FileP(Trg) {};
};
-
-// Description File
+ /*}}}*/
+// Description File /*{{{*/
class pkgCache::DescFileIterator
{
pkgCache *Owner;
@@ -412,8 +422,8 @@ class pkgCache::DescFileIterator
inline DescFileIterator() : Owner(0), FileP(0) {};
inline DescFileIterator(pkgCache &Owner,DescFile *Trg) : Owner(&Owner), FileP(Trg) {};
};
-
-// Inlined Begin functions cant be in the class because of order problems
+ /*}}}*/
+// Inlined Begin functions cant be in the class because of order problems /*{{{*/
inline pkgCache::VerIterator pkgCache::PkgIterator::VersionList() const
{return VerIterator(*Owner,Owner->VerP + Pkg->VersionList);};
inline pkgCache::VerIterator pkgCache::PkgIterator::CurrentVer() const
@@ -432,5 +442,5 @@ inline pkgCache::VerFileIterator pkgCache::VerIterator::FileList() const
{return VerFileIterator(*Owner,Owner->VerFileP + Ver->FileList);};
inline pkgCache::DescFileIterator pkgCache::DescIterator::FileList() const
{return DescFileIterator(*Owner,Owner->DescFileP + Desc->FileList);};
-
+ /*}}}*/
#endif
diff --git a/apt-pkg/cdrom.cc b/apt-pkg/cdrom.cc
index 8be26e2bc..72d8e4d41 100644
--- a/apt-pkg/cdrom.cc
+++ b/apt-pkg/cdrom.cc
@@ -160,7 +160,7 @@ bool pkgCdrom::FindPackages(string CD,
return !_error->PendingError();
}
-
+ /*}}}*/
// Score - We compute a 'score' for a path /*{{{*/
// ---------------------------------------------------------------------
/* Paths are scored based on how close they come to what I consider
@@ -210,7 +210,6 @@ int pkgCdrom::Score(string Path)
return Res;
}
-
/*}}}*/
// DropBinaryArch - Dump dirs with a string like /binary-<foo>/ /*{{{*/
// ---------------------------------------------------------------------
@@ -248,8 +247,7 @@ bool pkgCdrom::DropBinaryArch(vector<string> &List)
return true;
}
-
-
+ /*}}}*/
// DropRepeats - Drop repeated files resulting from symlinks /*{{{*/
// ---------------------------------------------------------------------
/* Here we go and stat every file that we found and strip dup inodes. */
@@ -304,7 +302,6 @@ bool pkgCdrom::DropRepeats(vector<string> &List,const char *Name)
return true;
}
/*}}}*/
-
// ReduceSourceList - Takes the path list and reduces it /*{{{*/
// ---------------------------------------------------------------------
/* This takes the list of source list expressed entires and collects
@@ -513,9 +510,8 @@ bool pkgCdrom::WriteSourceList(string Name,vector<string> &List,bool Source)
return true;
}
-
-
-bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log)
+ /*}}}*/
+bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log) /*{{{*/
{
stringstream msg;
@@ -573,9 +569,8 @@ bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log)
return true;
}
-
-
-bool pkgCdrom::Add(pkgCdromStatus *log)
+ /*}}}*/
+bool pkgCdrom::Add(pkgCdromStatus *log) /*{{{*/
{
stringstream msg;
@@ -844,16 +839,16 @@ bool pkgCdrom::Add(pkgCdromStatus *log)
return true;
}
-
-
-pkgUdevCdromDevices::pkgUdevCdromDevices()
+ /*}}}*/
+pkgUdevCdromDevices::pkgUdevCdromDevices() /*{{{*/
: libudev_handle(NULL)
{
}
+ /*}}}*/
bool
-pkgUdevCdromDevices::Dlopen()
+pkgUdevCdromDevices::Dlopen() /*{{{*/
{
// alread open
if(libudev_handle != NULL)
@@ -880,9 +875,9 @@ pkgUdevCdromDevices::Dlopen()
return true;
}
-
+ /*}}}*/
vector<CdromDevice>
-pkgUdevCdromDevices::Scan()
+pkgUdevCdromDevices::Scan() /*{{{*/
{
vector<CdromDevice> cdrom_devices;
struct udev_enumerate *enumerate;
@@ -922,9 +917,10 @@ pkgUdevCdromDevices::Scan()
}
return cdrom_devices;
}
+ /*}}}*/
-
-pkgUdevCdromDevices::~pkgUdevCdromDevices()
+pkgUdevCdromDevices::~pkgUdevCdromDevices() /*{{{*/
{
dlclose(libudev_handle);
}
+ /*}}}*/
diff --git a/apt-pkg/cdrom.h b/apt-pkg/cdrom.h
index 13e7203f4..14ca1d810 100644
--- a/apt-pkg/cdrom.h
+++ b/apt-pkg/cdrom.h
@@ -8,7 +8,7 @@
using namespace std;
-class pkgCdromStatus
+class pkgCdromStatus /*{{{*/
{
protected:
int totalSteps;
@@ -29,8 +29,8 @@ class pkgCdromStatus
// Progress indicator for the Index rewriter
virtual OpProgress* GetOpProgress() {return NULL; };
};
-
-class pkgCdrom
+ /*}}}*/
+class pkgCdrom /*{{{*/
{
protected:
enum {
@@ -65,17 +65,18 @@ class pkgCdrom
bool Ident(string &ident, pkgCdromStatus *log);
bool Add(pkgCdromStatus *log);
};
+ /*}}}*/
// class that uses libudev to find cdrom devices dynamically
-struct CdromDevice
+struct CdromDevice /*{{{*/
{
string DeviceName;
bool Mounted;
string MountPath;
};
-
-class pkgUdevCdromDevices
+ /*}}}*/
+class pkgUdevCdromDevices /*{{{*/
{
protected:
// libudev dlopen stucture
@@ -101,7 +102,6 @@ class pkgUdevCdromDevices
bool Dlopen();
vector<CdromDevice> Scan();
};
-
-
+ /*}}}*/
#endif
diff --git a/apt-pkg/clean.cc b/apt-pkg/clean.cc
index 3fa67e8e6..0d1dfbf74 100644
--- a/apt-pkg/clean.cc
+++ b/apt-pkg/clean.cc
@@ -19,7 +19,6 @@
#include <sys/stat.h>
#include <unistd.h>
/*}}}*/
-
// ArchiveCleaner::Go - Perform smart cleanup of the archive /*{{{*/
// ---------------------------------------------------------------------
/* Scan the directory for files to erase, we check the version information
diff --git a/apt-pkg/contrib/cdromutl.cc b/apt-pkg/contrib/cdromutl.cc
index 0cf9697ac..6dce82fe1 100644
--- a/apt-pkg/contrib/cdromutl.cc
+++ b/apt-pkg/contrib/cdromutl.cc
@@ -64,35 +64,44 @@ bool UnmountCdrom(string Path)
{
if (IsMounted(Path) == false)
return true;
-
- int Child = ExecFork();
- // The child
- if (Child == 0)
+ for (int i=0;i<3;i++)
{
- // Make all the fds /dev/null
- for (int I = 0; I != 3; I++)
- dup2(open("/dev/null",O_RDWR),I);
+
+ int Child = ExecFork();
- if (_config->Exists("Acquire::cdrom::"+Path+"::UMount") == true)
+ // The child
+ if (Child == 0)
{
- if (system(_config->Find("Acquire::cdrom::"+Path+"::UMount").c_str()) != 0)
+ // Make all the fds /dev/null
+ for (int I = 0; I != 3; I++)
+ dup2(open("/dev/null",O_RDWR),I);
+
+ if (_config->Exists("Acquire::cdrom::"+Path+"::UMount") == true)
+ {
+ if (system(_config->Find("Acquire::cdrom::"+Path+"::UMount").c_str()) != 0)
+ _exit(100);
+ _exit(0);
+ }
+ else
+ {
+ const char *Args[10];
+ Args[0] = "umount";
+ Args[1] = Path.c_str();
+ Args[2] = 0;
+ execvp(Args[0],(char **)Args);
_exit(100);
- _exit(0);
+ }
}
- else
- {
- const char *Args[10];
- Args[0] = "umount";
- Args[1] = Path.c_str();
- Args[2] = 0;
- execvp(Args[0],(char **)Args);
- _exit(100);
- }
+
+ // if it can not be umounted, give it a bit more time
+ // this can happen when auto-mount magic or fs/cdrom prober attack
+ if (ExecWait(Child,"umount",true) == true)
+ return true;
+ sleep(1);
}
- // Wait for mount
- return ExecWait(Child,"umount",true);
+ return false;
}
/*}}}*/
// MountCdrom - Mount a cdrom /*{{{*/
diff --git a/apt-pkg/contrib/configuration.cc b/apt-pkg/contrib/configuration.cc
index 7326b84ea..4e8586e83 100644
--- a/apt-pkg/contrib/configuration.cc
+++ b/apt-pkg/contrib/configuration.cc
@@ -182,9 +182,9 @@ string Configuration::FindFile(const char *Name,const char *Default) const
if (Itm == 0 || Itm->Value.empty() == true)
{
if (Default == 0)
- return "";
+ return rootDir;
else
- return Default;
+ return rootDir + Default;
}
string val = Itm->Value;
@@ -223,6 +223,25 @@ string Configuration::FindDir(const char *Name,const char *Default) const
return Res;
}
/*}}}*/
+// Configuration::FindVector - Find a vector of values /*{{{*/
+// ---------------------------------------------------------------------
+/* Returns a vector of config values under the given item */
+vector<string> Configuration::FindVector(const char *Name) const
+{
+ vector<string> Vec;
+ const Item *Top = Lookup(Name);
+ if (Top == NULL)
+ return Vec;
+
+ Item *I = Top->Child;
+ while(I != NULL)
+ {
+ Vec.push_back(I->Value);
+ I = I->Next;
+ }
+ return Vec;
+}
+ /*}}}*/
// Configuration::FindI - Find an integer value /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -521,6 +540,7 @@ bool ReadConfigFile(Configuration &Conf,const string &FName,bool AsSectional,
F.getline(Buffer,sizeof(Buffer) / 2);
Input += Buffer;
+ delete[] Buffer;
}
while (F.fail() && !F.eof());
@@ -581,9 +601,11 @@ bool ReadConfigFile(Configuration &Conf,const string &FName,bool AsSectional,
InQuote = !InQuote;
if (InQuote == true)
continue;
-
- if (*I == '/' && I + 1 != End && I[1] == '/')
- {
+
+ if ((*I == '/' && I + 1 != End && I[1] == '/') ||
+ (*I == '#' && strcmp(string(I,I+6).c_str(),"#clear") != 0 &&
+ strcmp(string(I,I+8).c_str(),"#include") != 0))
+ {
End = I;
break;
}
diff --git a/apt-pkg/contrib/configuration.h b/apt-pkg/contrib/configuration.h
index 2534692a3..e2da83f5b 100644
--- a/apt-pkg/contrib/configuration.h
+++ b/apt-pkg/contrib/configuration.h
@@ -31,6 +31,7 @@
#include <string>
+#include <vector>
#include <iostream>
using std::string;
@@ -70,6 +71,8 @@ class Configuration
string Find(const string Name,const char *Default = 0) const {return Find(Name.c_str(),Default);};
string FindFile(const char *Name,const char *Default = 0) const;
string FindDir(const char *Name,const char *Default = 0) const;
+ std::vector<string> FindVector(const string &Name) const;
+ std::vector<string> FindVector(const char *Name) const;
int FindI(const char *Name,int Default = 0) const;
int FindI(const string Name,int Default = 0) const {return FindI(Name.c_str(),Default);};
bool FindB(const char *Name,bool Default = false) const;
diff --git a/apt-pkg/contrib/error.cc b/apt-pkg/contrib/error.cc
index db8c53c36..927b7e05c 100644
--- a/apt-pkg/contrib/error.cc
+++ b/apt-pkg/contrib/error.cc
@@ -84,17 +84,17 @@ bool GlobalError::Errno(const char *Function,const char *Description,...)
char S[400];
vsnprintf(S,sizeof(S),Description,args);
snprintf(S + strlen(S),sizeof(S) - strlen(S),
- " - %s (%i %s)",Function,errno,strerror(errno));
+ " - %s (%i: %s)",Function,errno,strerror(errno));
// Put it on the list
Item *Itm = new Item;
Itm->Text = S;
Itm->Error = true;
Insert(Itm);
-
+
PendingFlag = true;
- return false;
+ return false;
}
/*}}}*/
// GlobalError::WarningE - Get part of the warn string from errno /*{{{*/
@@ -112,15 +112,16 @@ bool GlobalError::WarningE(const char *Function,const char *Description,...)
// sprintf the description
char S[400];
vsnprintf(S,sizeof(S),Description,args);
- snprintf(S + strlen(S),sizeof(S) - strlen(S)," - %s (%i %s)",Function,errno,strerror(errno));
+ snprintf(S + strlen(S),sizeof(S) - strlen(S),
+ " - %s (%i: %s)",Function,errno,strerror(errno));
// Put it on the list
Item *Itm = new Item;
Itm->Text = S;
Itm->Error = false;
Insert(Itm);
-
- return false;
+
+ return false;
}
/*}}}*/
// GlobalError::Error - Add an error to the list /*{{{*/
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc
index a7de09c44..4240d9f49 100644
--- a/apt-pkg/contrib/fileutl.cc
+++ b/apt-pkg/contrib/fileutl.cc
@@ -451,10 +451,12 @@ bool ExecWait(pid_t Pid,const char *Name,bool Reap)
if (Reap == true)
return false;
if (WIFSIGNALED(Status) != 0)
+ {
if( WTERMSIG(Status) == SIGSEGV)
return _error->Error(_("Sub-process %s received a segmentation fault."),Name);
else
return _error->Error(_("Sub-process %s received signal %u."),Name, WTERMSIG(Status));
+ }
if (WIFEXITED(Status) != 0)
return _error->Error(_("Sub-process %s returned an error code (%u)"),Name,WEXITSTATUS(Status));
diff --git a/apt-pkg/contrib/hashes.cc b/apt-pkg/contrib/hashes.cc
index fcc2f887c..b43771ea7 100644
--- a/apt-pkg/contrib/hashes.cc
+++ b/apt-pkg/contrib/hashes.cc
@@ -34,7 +34,7 @@ HashString::HashString(string Type, string Hash) : Type(Type), Hash(Hash)
{
}
-HashString::HashString(string StringedHash)
+HashString::HashString(string StringedHash) /*{{{*/
{
// legacy: md5sum without "MD5Sum:" prefix
if (StringedHash.find(":") == string::npos && StringedHash.size() == 32)
@@ -50,9 +50,8 @@ HashString::HashString(string StringedHash)
if(_config->FindB("Debug::Hashes",false) == true)
std::clog << "HashString(string): " << Type << " : " << Hash << std::endl;
}
-
-
-bool HashString::VerifyFile(string filename) const
+ /*}}}*/
+bool HashString::VerifyFile(string filename) const /*{{{*/
{
FileFd fd;
MD5Summation MD5;
@@ -83,7 +82,7 @@ bool HashString::VerifyFile(string filename) const
return (fileHash == Hash);
}
-
+ /*}}}*/
const char** HashString::SupportedHashes()
{
return _SupportedHashes;
@@ -94,13 +93,11 @@ bool HashString::empty() const
return (Type.empty() || Hash.empty());
}
-
string HashString::toStr() const
{
return Type+string(":")+Hash;
}
-
// Hashes::AddFD - Add the contents of the FD /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -108,11 +105,16 @@ bool Hashes::AddFD(int Fd,unsigned long Size)
{
unsigned char Buf[64*64];
int Res = 0;
- while (Size != 0)
+ int ToEOF = (Size == 0);
+ while (Size != 0 || ToEOF)
{
- Res = read(Fd,Buf,min(Size,(unsigned long)sizeof(Buf)));
- if (Res < 0 || (unsigned)Res != min(Size,(unsigned long)sizeof(Buf)))
- return false;
+ unsigned n = sizeof(Buf);
+ if (!ToEOF) n = min(Size,(unsigned long)n);
+ Res = read(Fd,Buf,n);
+ if (Res < 0 || (!ToEOF && (unsigned) Res != n)) // error, or short read
+ return false;
+ if (ToEOF && Res == 0) // EOF
+ break;
Size -= Res;
MD5.Add(Buf,Res);
SHA1.Add(Buf,Res);
diff --git a/apt-pkg/contrib/md5.cc b/apt-pkg/contrib/md5.cc
index a095f8f0f..2bfd70f1b 100644
--- a/apt-pkg/contrib/md5.cc
+++ b/apt-pkg/contrib/md5.cc
@@ -294,11 +294,16 @@ bool MD5Summation::AddFD(int Fd,unsigned long Size)
{
unsigned char Buf[64*64];
int Res = 0;
- while (Size != 0)
+ int ToEOF = (Size == 0);
+ while (Size != 0 || ToEOF)
{
- Res = read(Fd,Buf,min(Size,(unsigned long)sizeof(Buf)));
- if (Res < 0 || (unsigned)Res != min(Size,(unsigned long)sizeof(Buf)))
- return false;
+ unsigned n = sizeof(Buf);
+ if (!ToEOF) n = min(Size,(unsigned long)n);
+ Res = read(Fd,Buf,n);
+ if (Res < 0 || (!ToEOF && (unsigned) Res != n)) // error, or short read
+ return false;
+ if (ToEOF && Res == 0) // EOF
+ break;
Size -= Res;
Add(Buf,Res);
}
diff --git a/apt-pkg/contrib/mmap.cc b/apt-pkg/contrib/mmap.cc
index 04a45811b..4d5fcf71e 100644
--- a/apt-pkg/contrib/mmap.cc
+++ b/apt-pkg/contrib/mmap.cc
@@ -13,11 +13,6 @@
libc6 generates warnings -- which should be errors, g++ isn't properly
strict.
- The configure test notes that some OS's have broken private mmap's
- so on those OS's we can't use mmap. This means we have to use
- configure to test mmap and can't rely on the POSIX
- _POSIX_MAPPED_FILES test.
-
##################################################################### */
/*}}}*/
// Include Files /*{{{*/
@@ -31,6 +26,7 @@
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
+#include <stdlib.h>
#include <cstring>
/*}}}*/
@@ -144,7 +140,7 @@ bool MMap::Sync(unsigned long Start,unsigned long Stop)
// DynamicMMap::DynamicMMap - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
-DynamicMMap::DynamicMMap(FileFd &F,unsigned long Flags,unsigned long WorkSpace) :
+DynamicMMap::DynamicMMap(FileFd &F,unsigned long Flags,unsigned long WorkSpace) :
MMap(F,Flags | NoImmMap), Fd(&F), WorkSpace(WorkSpace)
{
if (_error->PendingError() == true)
@@ -166,15 +162,34 @@ DynamicMMap::DynamicMMap(FileFd &F,unsigned long Flags,unsigned long WorkSpace)
/*}}}*/
// DynamicMMap::DynamicMMap - Constructor for a non-file backed map /*{{{*/
// ---------------------------------------------------------------------
-/* This is just a fancy malloc really.. */
+/* We try here to use mmap to reserve some space - this is much more
+ cooler than the fallback solution to simply allocate a char array
+ and could come in handy later than we are able to grow such an mmap */
DynamicMMap::DynamicMMap(unsigned long Flags,unsigned long WorkSpace) :
MMap(Flags | NoImmMap | UnMapped), Fd(0), WorkSpace(WorkSpace)
{
if (_error->PendingError() == true)
return;
-
+
+#ifdef _POSIX_MAPPED_FILES
+ // Set the permissions.
+ int Prot = PROT_READ;
+ int Map = MAP_PRIVATE | MAP_ANONYMOUS;
+ if ((Flags & ReadOnly) != ReadOnly)
+ Prot |= PROT_WRITE;
+ if ((Flags & Public) == Public)
+ Map = MAP_SHARED | MAP_ANONYMOUS;
+
+ // use anonymous mmap() to get the memory
+ Base = (unsigned char*) mmap(0, WorkSpace, Prot, Map, -1, 0);
+
+ if(Base == MAP_FAILED)
+ _error->Errno("DynamicMMap",_("Couldn't make mmap of %lu bytes"),WorkSpace);
+#else
+ // fallback to a static allocated space
Base = new unsigned char[WorkSpace];
memset(Base,0,WorkSpace);
+#endif
iSize = 0;
}
/*}}}*/
@@ -185,7 +200,11 @@ DynamicMMap::~DynamicMMap()
{
if (Fd == 0)
{
+#ifdef _POSIX_MAPPED_FILES
+ munmap(Base, WorkSpace);
+#else
delete [] (unsigned char *)Base;
+#endif
return;
}
@@ -204,17 +223,19 @@ unsigned long DynamicMMap::RawAllocate(unsigned long Size,unsigned long Aln)
unsigned long Result = iSize;
if (Aln != 0)
Result += Aln - (iSize%Aln);
-
+
iSize = Result + Size;
-
- // Just in case error check
- if (Result + Size > WorkSpace)
+
+ // try to grow the buffer
+ while(Result + Size > WorkSpace)
{
- _error->Error(_("Dynamic MMap ran out of room. Please increase the size "
- "of APT::Cache-Limit. Current value: %lu. (man 5 apt.conf)"), WorkSpace);
- return 0;
+ if(!Grow())
+ {
+ _error->Error(_("Dynamic MMap ran out of room. Please increase the size "
+ "of APT::Cache-Limit. Current value: %lu. (man 5 apt.conf)"), WorkSpace);
+ return 0;
+ }
}
-
return Result;
}
/*}}}*/
@@ -223,7 +244,7 @@ unsigned long DynamicMMap::RawAllocate(unsigned long Size,unsigned long Aln)
/* This allocates an Item of size ItemSize so that it is aligned to its
size in the file. */
unsigned long DynamicMMap::Allocate(unsigned long ItemSize)
-{
+{
// Look for a matching pool entry
Pool *I;
Pool *Empty = 0;
@@ -234,7 +255,6 @@ unsigned long DynamicMMap::Allocate(unsigned long ItemSize)
if (I->ItemSize == ItemSize)
break;
}
-
// No pool is allocated, use an unallocated one
if (I == Pools + PoolCount)
{
@@ -249,17 +269,24 @@ unsigned long DynamicMMap::Allocate(unsigned long ItemSize)
I->ItemSize = ItemSize;
I->Count = 0;
}
-
+
+ unsigned long Result = 0;
// Out of space, allocate some more
if (I->Count == 0)
{
- I->Count = 20*1024/ItemSize;
- I->Start = RawAllocate(I->Count*ItemSize,ItemSize);
- }
+ const unsigned long size = 20*1024;
+ I->Count = size/ItemSize;
+ Result = RawAllocate(size,ItemSize);
+ // Does the allocation failed ?
+ if (Result == 0 && _error->PendingError())
+ return 0;
+ I->Start = Result;
+ }
+ else
+ Result = I->Start;
I->Count--;
- unsigned long Result = I->Start;
- I->Start += ItemSize;
+ I->Start += ItemSize;
return Result/ItemSize;
}
/*}}}*/
@@ -269,20 +296,45 @@ unsigned long DynamicMMap::Allocate(unsigned long ItemSize)
unsigned long DynamicMMap::WriteString(const char *String,
unsigned long Len)
{
- unsigned long Result = iSize;
- // Just in case error check
- if (Result + Len > WorkSpace)
- {
- _error->Error(_("Dynamic MMap ran out of room. Please increase the size "
- "of APT::Cache-Limit. Current value: %lu. (man 5 apt.conf)"), WorkSpace);
- return 0;
- }
-
if (Len == (unsigned long)-1)
Len = strlen(String);
- iSize += Len + 1;
+
+ unsigned long Result = RawAllocate(Len+1,0);
+
+ if (Result == 0 && _error->PendingError())
+ return 0;
+
memcpy((char *)Base + Result,String,Len);
((char *)Base)[Result + Len] = 0;
return Result;
}
/*}}}*/
+// DynamicMMap::Grow - Grow the mmap /*{{{*/
+// ---------------------------------------------------------------------
+/* This method will try to grow the mmap we currently use. This doesn't
+ work most of the time because we can't move the mmap around in the
+ memory for now as this would require to adjust quite a lot of pointers
+ but why we should not at least try to grow it before we give up? */
+bool DynamicMMap::Grow()
+{
+#if defined(_POSIX_MAPPED_FILES) && defined(__linux__)
+ unsigned long newSize = WorkSpace + 1024*1024;
+
+ if(Fd != 0)
+ {
+ Fd->Seek(newSize - 1);
+ char C = 0;
+ Fd->Write(&C,sizeof(C));
+ }
+
+ Base = mremap(Base, WorkSpace, newSize, 0);
+ if(Base == MAP_FAILED)
+ return false;
+
+ WorkSpace = newSize;
+ return true;
+#else
+ return false;
+#endif
+}
+ /*}}}*/
diff --git a/apt-pkg/contrib/mmap.h b/apt-pkg/contrib/mmap.h
index 19cf7582d..bde62217d 100644
--- a/apt-pkg/contrib/mmap.h
+++ b/apt-pkg/contrib/mmap.h
@@ -84,6 +84,8 @@ class DynamicMMap : public MMap
unsigned long WorkSpace;
Pool *Pools;
unsigned int PoolCount;
+
+ bool Grow();
public:
diff --git a/apt-pkg/contrib/netrc.cc b/apt-pkg/contrib/netrc.cc
new file mode 100644
index 000000000..d8027fc24
--- /dev/null
+++ b/apt-pkg/contrib/netrc.cc
@@ -0,0 +1,211 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: netrc.c,v 1.38 2007-11-07 09:21:35 bagder Exp $
+/* ######################################################################
+
+ netrc file parser - returns the login and password of a give host in
+ a specified netrc-type file
+
+ Originally written by Daniel Stenberg, <daniel@haxx.se>, et al. and
+ placed into the Public Domain, do with it what you will.
+
+ ##################################################################### */
+ /*}}}*/
+
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/fileutl.h>
+#include <iostream>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <pwd.h>
+
+#include "netrc.h"
+
+
+/* Get user and password from .netrc when given a machine name */
+
+enum {
+ NOTHING,
+ HOSTFOUND, /* the 'machine' keyword was found */
+ HOSTCOMPLETE, /* the machine name following the keyword was found too */
+ HOSTVALID, /* this is "our" machine! */
+ HOSTEND /* LAST enum */
+};
+
+/* make sure we have room for at least this size: */
+#define LOGINSIZE 64
+#define PASSWORDSIZE 64
+#define NETRC DOT_CHAR "netrc"
+
+/* returns -1 on failure, 0 if the host is found, 1 is the host isn't found */
+int parsenetrc (char *host, char *login, char *password, char *netrcfile = NULL)
+{
+ FILE *file;
+ int retcode = 1;
+ int specific_login = (login[0] != 0);
+ char *home = NULL;
+ bool netrc_alloc = false;
+ int state = NOTHING;
+
+ char state_login = 0; /* Found a login keyword */
+ char state_password = 0; /* Found a password keyword */
+ int state_our_login = false; /* With specific_login,
+ found *our* login name */
+
+ if (!netrcfile) {
+ home = getenv ("HOME"); /* portable environment reader */
+
+ if (!home) {
+ struct passwd *pw;
+ pw = getpwuid (geteuid ());
+ if(pw)
+ home = pw->pw_dir;
+ }
+
+ if (!home)
+ return -1;
+
+ asprintf (&netrcfile, "%s%s%s", home, DIR_CHAR, NETRC);
+ if(!netrcfile)
+ return -1;
+ else
+ netrc_alloc = true;
+ }
+
+ file = fopen (netrcfile, "r");
+ if(file) {
+ char *tok;
+ char *tok_buf;
+ bool done = false;
+ char netrcbuffer[256];
+
+ while (!done && fgets(netrcbuffer, sizeof (netrcbuffer), file)) {
+ tok = strtok_r (netrcbuffer, " \t\n", &tok_buf);
+ while (!done && tok) {
+ if(login[0] && password[0]) {
+ done = true;
+ break;
+ }
+
+ switch(state) {
+ case NOTHING:
+ if (!strcasecmp ("machine", tok)) {
+ /* the next tok is the machine name, this is in itself the
+ delimiter that starts the stuff entered for this machine,
+ after this we need to search for 'login' and
+ 'password'. */
+ state = HOSTFOUND;
+ }
+ break;
+ case HOSTFOUND:
+ /* extended definition of a "machine" if we have a "/"
+ we match the start of the string (host.startswith(token) */
+ if ((strchr(host, '/') && strstr(host, tok) == host) ||
+ (!strcasecmp (host, tok))) {
+ /* and yes, this is our host! */
+ state = HOSTVALID;
+ retcode = 0; /* we did find our host */
+ }
+ else
+ /* not our host */
+ state = NOTHING;
+ break;
+ case HOSTVALID:
+ /* we are now parsing sub-keywords concerning "our" host */
+ if (state_login) {
+ if (specific_login)
+ state_our_login = !strcasecmp (login, tok);
+ else
+ strncpy (login, tok, LOGINSIZE - 1);
+ state_login = 0;
+ } else if (state_password) {
+ if (state_our_login || !specific_login)
+ strncpy (password, tok, PASSWORDSIZE - 1);
+ state_password = 0;
+ } else if (!strcasecmp ("login", tok))
+ state_login = 1;
+ else if (!strcasecmp ("password", tok))
+ state_password = 1;
+ else if(!strcasecmp ("machine", tok)) {
+ /* ok, there's machine here go => */
+ state = HOSTFOUND;
+ state_our_login = false;
+ }
+ break;
+ } /* switch (state) */
+
+ tok = strtok_r (NULL, " \t\n", &tok_buf);
+ } /* while(tok) */
+ } /* while fgets() */
+
+ fclose(file);
+ }
+
+ if (netrc_alloc)
+ free(netrcfile);
+
+ return retcode;
+}
+
+void maybe_add_auth (URI &Uri, string NetRCFile)
+{
+ if (_config->FindB("Debug::Acquire::netrc", false) == true)
+ std::clog << "maybe_add_auth: " << (string)Uri
+ << " " << NetRCFile << std::endl;
+ if (Uri.Password.empty () == true || Uri.User.empty () == true)
+ {
+ if (NetRCFile.empty () == false)
+ {
+ char login[64] = "";
+ char password[64] = "";
+ char *netrcfile = strdupa (NetRCFile.c_str ());
+
+ // first check for a generic host based netrc entry
+ char *host = strdupa (Uri.Host.c_str ());
+ if (host && parsenetrc (host, login, password, netrcfile) == 0)
+ {
+ if (_config->FindB("Debug::Acquire::netrc", false) == true)
+ std::clog << "host: " << host
+ << " user: " << login
+ << " pass-size: " << strlen(password)
+ << std::endl;
+ Uri.User = string (login);
+ Uri.Password = string (password);
+ return;
+ }
+
+ // if host did not work, try Host+Path next, this will trigger
+ // a lookup uri.startswith(host) in the netrc file parser (because
+ // of the "/"
+ char *hostpath = strdupa (string(Uri.Host+Uri.Path).c_str ());
+ if (hostpath && parsenetrc (hostpath, login, password, netrcfile) == 0)
+ {
+ if (_config->FindB("Debug::Acquire::netrc", false) == true)
+ std::clog << "hostpath: " << hostpath
+ << " user: " << login
+ << " pass-size: " << strlen(password)
+ << std::endl;
+ Uri.User = string (login);
+ Uri.Password = string (password);
+ return;
+ }
+ }
+ }
+}
+
+#ifdef DEBUG
+int main(int argc, char* argv[])
+{
+ char login[64] = "";
+ char password[64] = "";
+
+ if(argc < 2)
+ return -1;
+
+ if(0 == parsenetrc (argv[1], login, password, argv[2])) {
+ printf("HOST: %s LOGIN: %s PASSWORD: %s\n", argv[1], login, password);
+ }
+}
+#endif
diff --git a/apt-pkg/contrib/netrc.h b/apt-pkg/contrib/netrc.h
new file mode 100644
index 000000000..02a5eb09f
--- /dev/null
+++ b/apt-pkg/contrib/netrc.h
@@ -0,0 +1,29 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: netrc.h,v 1.11 2004/01/07 09:19:35 bagder Exp $
+/* ######################################################################
+
+ netrc file parser - returns the login and password of a give host in
+ a specified netrc-type file
+
+ Originally written by Daniel Stenberg, <daniel@haxx.se>, et al. and
+ placed into the Public Domain, do with it what you will.
+
+ ##################################################################### */
+ /*}}}*/
+#ifndef NETRC_H
+#define NETRC_H
+
+#include <apt-pkg/strutl.h>
+
+#define DOT_CHAR "."
+#define DIR_CHAR "/"
+
+// Assume: password[0]=0, host[0] != 0.
+// If login[0] = 0, search for login and password within a machine section
+// in the netrc.
+// If login[0] != 0, search for password within machine and login.
+int parsenetrc (char *host, char *login, char *password, char *filename);
+
+void maybe_add_auth (URI &Uri, string NetRCFile);
+#endif
diff --git a/apt-pkg/contrib/sha256.cc b/apt-pkg/contrib/sha256.cc
index ecda3d8e8..e380c13ae 100644
--- a/apt-pkg/contrib/sha256.cc
+++ b/apt-pkg/contrib/sha256.cc
@@ -1,5 +1,5 @@
/*
- * Cryptographic API.
+ * Cryptographic API. {{{
*
* SHA-256, as specified in
* http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf
@@ -17,7 +17,7 @@
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
- */
+ */ /*}}}*/
#ifdef __GNUG__
#pragma implementation "apt-pkg/sha256.h"
@@ -65,20 +65,20 @@ static inline u32 Maj(u32 x, u32 y, u32 z)
#define H6 0x1f83d9ab
#define H7 0x5be0cd19
-static inline void LOAD_OP(int I, u32 *W, const u8 *input)
+static inline void LOAD_OP(int I, u32 *W, const u8 *input) /*{{{*/
{
W[I] = ( ((u32) input[I * 4 + 0] << 24)
| ((u32) input[I * 4 + 1] << 16)
| ((u32) input[I * 4 + 2] << 8)
| ((u32) input[I * 4 + 3]));
}
-
+ /*}}}*/
static inline void BLEND_OP(int I, u32 *W)
{
W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16];
}
-static void sha256_transform(u32 *state, const u8 *input)
+static void sha256_transform(u32 *state, const u8 *input) /*{{{*/
{
u32 a, b, c, d, e, f, g, h, t1, t2;
u32 W[64];
@@ -240,8 +240,8 @@ static void sha256_transform(u32 *state, const u8 *input)
a = b = c = d = e = f = g = h = t1 = t2 = 0;
memset(W, 0, 64 * sizeof(u32));
}
-
-SHA256Summation::SHA256Summation()
+ /*}}}*/
+SHA256Summation::SHA256Summation() /*{{{*/
{
Sum.state[0] = H0;
Sum.state[1] = H1;
@@ -255,8 +255,8 @@ SHA256Summation::SHA256Summation()
memset(Sum.buf, 0, sizeof(Sum.buf));
Done = false;
}
-
-bool SHA256Summation::Add(const u8 *data, unsigned long len)
+ /*}}}*/
+bool SHA256Summation::Add(const u8 *data, unsigned long len) /*{{{*/
{
struct sha256_ctx *sctx = &Sum;
unsigned int i, index, part_len;
@@ -291,8 +291,8 @@ bool SHA256Summation::Add(const u8 *data, unsigned long len)
return true;
}
-
-SHA256SumValue SHA256Summation::Result()
+ /*}}}*/
+SHA256SumValue SHA256Summation::Result() /*{{{*/
{
struct sha256_ctx *sctx = &Sum;
if (!Done) {
@@ -340,7 +340,7 @@ SHA256SumValue SHA256Summation::Result()
return res;
}
-
+ /*}}}*/
// SHA256SumValue::SHA256SumValue - Constructs the sum from a string /*{{{*/
// ---------------------------------------------------------------------
/* The string form of a SHA256 is a 64 character hex number */
@@ -349,7 +349,6 @@ SHA256SumValue::SHA256SumValue(string Str)
memset(Sum,0,sizeof(Sum));
Set(Str);
}
-
/*}}}*/
// SHA256SumValue::SHA256SumValue - Default constructor /*{{{*/
// ---------------------------------------------------------------------
@@ -358,7 +357,6 @@ SHA256SumValue::SHA256SumValue()
{
memset(Sum,0,sizeof(Sum));
}
-
/*}}}*/
// SHA256SumValue::Set - Set the sum from a string /*{{{*/
// ---------------------------------------------------------------------
@@ -391,9 +389,7 @@ string SHA256SumValue::Value() const
return string(Result);
}
-
-
-
+ /*}}}*/
// SHA256SumValue::operator == - Comparator /*{{{*/
// ---------------------------------------------------------------------
/* Call memcmp on the buffer */
@@ -402,8 +398,6 @@ bool SHA256SumValue::operator == (const SHA256SumValue & rhs) const
return memcmp(Sum,rhs.Sum,sizeof(Sum)) == 0;
}
/*}}}*/
-
-
// SHA256Summation::AddFD - Add content of file into the checksum /*{{{*/
// ---------------------------------------------------------------------
/* */
diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc
index 0b1bc3c98..4c05f2df8 100644
--- a/apt-pkg/contrib/strutl.cc
+++ b/apt-pkg/contrib/strutl.cc
@@ -67,9 +67,20 @@ bool UTF8ToCodeset(const char *codeset, const string &orig, string *dest)
outbuf = new char[insize+1];
outptr = outbuf;
- iconv(cd, &inptr, &insize, &outptr, &outsize);
- *outptr = '\0';
+ while (insize != 0)
+ {
+ size_t const err = iconv(cd, &inptr, &insize, &outptr, &outsize);
+ if (err == (size_t)(-1))
+ {
+ insize--;
+ outsize++;
+ inptr++;
+ *outptr = '?';
+ outptr++;
+ }
+ }
+ *outptr = '\0';
*dest = outbuf;
delete[] outbuf;
@@ -304,13 +315,13 @@ string SizeToStr(double Size)
{
if (ASize < 100 && I != 0)
{
- sprintf(S,"%.1f%c",ASize,Ext[I]);
+ sprintf(S,"%'.1f%c",ASize,Ext[I]);
break;
}
if (ASize < 10000)
{
- sprintf(S,"%.0f%c",ASize,Ext[I]);
+ sprintf(S,"%'.0f%c",ASize,Ext[I]);
break;
}
ASize /= 1000.0;
@@ -387,6 +398,17 @@ string SubstVar(string Str,const struct SubstVar *Vars)
return Str;
}
/*}}}*/
+// OutputInDepth - return a string with separator multiplied with depth /*{{{*/
+// ---------------------------------------------------------------------
+/* Returns a string with the supplied separator depth + 1 times in it */
+std::string OutputInDepth(const unsigned long Depth, const char* Separator)
+{
+ std::string output = "";
+ for(unsigned long d=Depth+1; d > 0; d--)
+ output.append(Separator);
+ return output;
+}
+ /*}}}*/
// URItoFileName - Convert the uri into a unique file name /*{{{*/
// ---------------------------------------------------------------------
/* This converts a URI into a safe filename. It quotes all unsafe characters
diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h
index 51416a24a..2b2e147fb 100644
--- a/apt-pkg/contrib/strutl.h
+++ b/apt-pkg/contrib/strutl.h
@@ -48,6 +48,7 @@ string DeQuoteString(const string &Str);
string SizeToStr(double Bytes);
string TimeToStr(unsigned long Sec);
string Base64Encode(const string &Str);
+string OutputInDepth(const unsigned long Depth, const char* Separator=" ");
string URItoFileName(const string &URI);
string TimeRFC1123(time_t Date);
bool StrToTime(const string &Val,time_t &Result);
@@ -65,16 +66,17 @@ bool CheckDomainList(const string &Host, const string &List);
int tolower_ascii(int c);
#define APT_MKSTRCMP(name,func) \
+inline int name(const char *A,const char *B) {return func(A,A+strlen(A),B,B+strlen(B));}; \
inline int name(const char *A,const char *AEnd,const char *B) {return func(A,AEnd,B,B+strlen(B));}; \
-inline int name(string A,const char *B) {return func(A.c_str(),A.c_str()+A.length(),B,B+strlen(B));}; \
-inline int name(string A,string B) {return func(A.c_str(),A.c_str()+A.length(),B.c_str(),B.c_str()+B.length());}; \
-inline int name(string A,const char *B,const char *BEnd) {return func(A.c_str(),A.c_str()+A.length(),B,BEnd);};
+inline int name(const string& A,const char *B) {return func(A.c_str(),A.c_str()+A.length(),B,B+strlen(B));}; \
+inline int name(const string& A,const string& B) {return func(A.c_str(),A.c_str()+A.length(),B.c_str(),B.c_str()+B.length());}; \
+inline int name(const string& A,const char *B,const char *BEnd) {return func(A.c_str(),A.c_str()+A.length(),B,BEnd);};
#define APT_MKSTRCMP2(name,func) \
inline int name(const char *A,const char *AEnd,const char *B) {return func(A,AEnd,B,B+strlen(B));}; \
-inline int name(string A,const char *B) {return func(A.begin(),A.end(),B,B+strlen(B));}; \
-inline int name(string A,string B) {return func(A.begin(),A.end(),B.begin(),B.end());}; \
-inline int name(string A,const char *B,const char *BEnd) {return func(A.begin(),A.end(),B,BEnd);};
+inline int name(const string& A,const char *B) {return func(A.begin(),A.end(),B,B+strlen(B));}; \
+inline int name(const string& A,const string& B) {return func(A.begin(),A.end(),B.begin(),B.end());}; \
+inline int name(const string& A,const char *B,const char *BEnd) {return func(A.begin(),A.end(),B,BEnd);};
int stringcmp(const char *A,const char *AEnd,const char *B,const char *BEnd);
int stringcasecmp(const char *A,const char *AEnd,const char *B,const char *BEnd);
diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc
index 55ba1f8c4..517b771a5 100644
--- a/apt-pkg/deb/deblistparser.cc
+++ b/apt-pkg/deb/deblistparser.cc
@@ -109,6 +109,8 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver)
return false;
if (ParseDepends(Ver,"Replaces",pkgCache::Dep::Replaces) == false)
return false;
+ if (ParseDepends(Ver,"Enhances",pkgCache::Dep::Enhances) == false)
+ return false;
// Obsolete.
if (ParseDepends(Ver,"Optional",pkgCache::Dep::Suggests) == false)
@@ -637,6 +639,8 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator FileI,
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)
diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc
index ee035191f..f3ab6960c 100644
--- a/apt-pkg/deb/debmetaindex.cc
+++ b/apt-pkg/deb/debmetaindex.cc
@@ -115,6 +115,13 @@ debReleaseIndex::debReleaseIndex(string URI,string Dist)
this->Type = "deb";
}
+debReleaseIndex::~debReleaseIndex()
+{
+ for (vector<const debSectionEntry *>::const_iterator I = SectionEntries.begin();
+ I != SectionEntries.end(); I++)
+ delete *I;
+}
+
vector <struct IndexTarget *>* debReleaseIndex::ComputeIndexTargets() const
{
vector <struct IndexTarget *>* IndexTargets = new vector <IndexTarget *>;
diff --git a/apt-pkg/deb/debmetaindex.h b/apt-pkg/deb/debmetaindex.h
index c021a1b5a..8e6a1463b 100644
--- a/apt-pkg/deb/debmetaindex.h
+++ b/apt-pkg/deb/debmetaindex.h
@@ -22,6 +22,7 @@ class debReleaseIndex : public metaIndex {
public:
debReleaseIndex(string URI, string Dist);
+ ~debReleaseIndex();
virtual string ArchiveURI(string File) const {return URI + File;};
virtual bool GetIndexes(pkgAcquire *Owner, bool GetAll=false) const;
diff --git a/apt-pkg/deb/debsrcrecords.cc b/apt-pkg/deb/debsrcrecords.cc
index ace4e00b5..bde10aa6d 100644
--- a/apt-pkg/deb/debsrcrecords.cc
+++ b/apt-pkg/deb/debsrcrecords.cc
@@ -135,9 +135,15 @@ bool debSrcRecordParser::Files(vector<pkgSrcRecords::File> &List)
string::size_type Tmp = F.Path.rfind('.',Pos);
if (Tmp == string::npos)
break;
+ if (F.Type == "tar") {
+ // source v3 has extension 'debian.tar.*' instead of 'diff.*'
+ if (string(F.Path, Tmp+1, Pos-Tmp) == "debian")
+ F.Type = "diff";
+ break;
+ }
F.Type = string(F.Path,Tmp+1,Pos-Tmp);
- if (F.Type == "gz" || F.Type == "bz2" || F.Type == "lzma")
+ if (F.Type == "gz" || F.Type == "bz2" || F.Type == "lzma" || F.Type == "tar")
{
Pos = Tmp-1;
continue;
@@ -152,3 +158,11 @@ bool debSrcRecordParser::Files(vector<pkgSrcRecords::File> &List)
return true;
}
/*}}}*/
+// SrcRecordParser::~SrcRecordParser - Destructor /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+debSrcRecordParser::~debSrcRecordParser()
+{
+ delete[] Buffer;
+}
+ /*}}}*/
diff --git a/apt-pkg/deb/debsrcrecords.h b/apt-pkg/deb/debsrcrecords.h
index 8b1237ccd..a3b5a8286 100644
--- a/apt-pkg/deb/debsrcrecords.h
+++ b/apt-pkg/deb/debsrcrecords.h
@@ -50,6 +50,7 @@ class debSrcRecordParser : public pkgSrcRecords::Parser
debSrcRecordParser(string File,pkgIndexFile const *Index)
: Parser(Index), Fd(File,FileFd::ReadOnly), Tags(&Fd,102400),
Buffer(0), BufSize(0) {}
+ ~debSrcRecordParser();
};
#endif
diff --git a/apt-pkg/deb/debsystem.cc b/apt-pkg/deb/debsystem.cc
index 82464d998..59f826d96 100644
--- a/apt-pkg/deb/debsystem.cc
+++ b/apt-pkg/deb/debsystem.cc
@@ -17,8 +17,8 @@
#include <apt-pkg/configuration.h>
#include <apt-pkg/error.h>
#include <apt-pkg/fileutl.h>
-#include <apti18n.h>
-
+#include <apti18n.h>
+
#include <sys/types.h>
#include <unistd.h>
#include <dirent.h>
diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc
index a8d08f500..88098c379 100644
--- a/apt-pkg/deb/dpkgpm.cc
+++ b/apt-pkg/deb/dpkgpm.cc
@@ -49,6 +49,7 @@ namespace
std::make_pair("install", N_("Installing %s")),
std::make_pair("configure", N_("Configuring %s")),
std::make_pair("remove", N_("Removing %s")),
+ std::make_pair("purge", N_("Completely removing %s")),
std::make_pair("trigproc", N_("Running post-installation trigger %s"))
};
@@ -134,8 +135,14 @@ bool pkgDPkgPM::Configure(PkgIterator Pkg)
{
if (Pkg.end() == true)
return false;
-
- List.push_back(Item(Item::Configure,Pkg));
+
+ List.push_back(Item(Item::Configure, Pkg));
+
+ // Use triggers for config calls if we configure "smart"
+ // as otherwise Pre-Depends will not be satisfied, see #526774
+ if (_config->FindB("DPkg::TriggersPending", false) == true)
+ List.push_back(Item(Item::TriggersPending, PkgIterator()));
+
return true;
}
/*}}}*/
@@ -190,6 +197,9 @@ bool pkgDPkgPM::SendV2Pkgs(FILE *F)
// Write out the package actions in order.
for (vector<Item>::iterator I = List.begin(); I != List.end(); I++)
{
+ if(I->Pkg.end() == true)
+ continue;
+
pkgDepCache::StateCache &S = Cache[I->Pkg];
fprintf(F,"%s ",I->Pkg.Name());
@@ -378,10 +388,11 @@ void pkgDPkgPM::DoTerminalPty(int master)
*/
void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line)
{
+ bool const Debug = _config->FindB("Debug::pkgDPkgProgressReporting",false);
// the status we output
ostringstream status;
- if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
+ if (Debug == true)
std::clog << "got from dpkg '" << line << "'" << std::endl;
@@ -396,6 +407,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line)
'processing: install: pkg'
'processing: configure: pkg'
'processing: remove: pkg'
+ 'processing: purge: pkg' - but for apt is it a ignored "unknown" action
'processing: trigproc: trigger'
*/
@@ -408,28 +420,28 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line)
TokSplitString(':', line, list, sizeof(list)/sizeof(list[0]));
if( list[0] == NULL || list[1] == NULL || list[2] == NULL)
{
- if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
+ if (Debug == true)
std::clog << "ignoring line: not enough ':'" << std::endl;
return;
}
- char *pkg = list[1];
- char *action = _strstrip(list[2]);
+ const char* const pkg = list[1];
+ const char* action = _strstrip(list[2]);
// 'processing' from dpkg looks like
// 'processing: action: pkg'
if(strncmp(list[0], "processing", strlen("processing")) == 0)
{
char s[200];
- char *pkg_or_trigger = _strstrip(list[2]);
- action =_strstrip( list[1]);
+ const char* const pkg_or_trigger = _strstrip(list[2]);
+ action = _strstrip( list[1]);
const std::pair<const char *, const char *> * const iter =
std::find_if(PackageProcessingOpsBegin,
PackageProcessingOpsEnd,
MatchProcessingOp(action));
if(iter == PackageProcessingOpsEnd)
{
- if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
- std::clog << "ignoring unknwon action: " << action << std::endl;
+ if (Debug == true)
+ std::clog << "ignoring unknown action: " << action << std::endl;
return;
}
snprintf(s, sizeof(s), _(iter->second), pkg_or_trigger);
@@ -440,7 +452,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line)
<< endl;
if(OutStatusFd > 0)
write(OutStatusFd, status.str().c_str(), status.str().size());
- if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
+ if (Debug == true)
std::clog << "send: '" << status.str() << "'" << endl;
return;
}
@@ -453,11 +465,11 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line)
<< endl;
if(OutStatusFd > 0)
write(OutStatusFd, status.str().c_str(), status.str().size());
- if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
+ if (Debug == true)
std::clog << "send: '" << status.str() << "'" << endl;
return;
}
- if(strncmp(action,"conffile",strlen("conffile")) == 0)
+ else if(strncmp(action,"conffile",strlen("conffile")) == 0)
{
status << "pmconffile:" << list[1]
<< ":" << (PackagesDone/float(PackagesTotal)*100.0)
@@ -465,12 +477,12 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line)
<< endl;
if(OutStatusFd > 0)
write(OutStatusFd, status.str().c_str(), status.str().size());
- if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
+ if (Debug == true)
std::clog << "send: '" << status.str() << "'" << endl;
return;
}
- vector<struct DpkgState> &states = PackageOps[pkg];
+ vector<struct DpkgState> const &states = PackageOps[pkg];
const char *next_action = NULL;
if(PackageOpsDone[pkg] < states.size())
next_action = states[PackageOpsDone[pkg]].state;
@@ -493,15 +505,15 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line)
<< endl;
if(OutStatusFd > 0)
write(OutStatusFd, status.str().c_str(), status.str().size());
- if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
+ if (Debug == true)
std::clog << "send: '" << status.str() << "'" << endl;
}
- if (_config->FindB("Debug::pkgDPkgProgressReporting",false) == true)
+ if (Debug == true)
std::clog << "(parsed from dpkg) pkg: " << pkg
<< " action: " << action << endl;
}
-
-// DPkgPM::DoDpkgStatusFd /*{{{*/
+ /*}}}*/
+// DPkgPM::DoDpkgStatusFd /*{{{*/
// ---------------------------------------------------------------------
/*
*/
@@ -538,47 +550,106 @@ void pkgDPkgPM::DoDpkgStatusFd(int statusfd, int OutStatusFd)
dpkgbuf_pos = dpkgbuf+dpkgbuf_pos-p;
}
/*}}}*/
-
+// DPkgPM::WriteHistoryTag /*{{{*/
+void pkgDPkgPM::WriteHistoryTag(string tag, string value)
+{
+ if (value.size() > 0)
+ {
+ // poor mans rstrip(", ")
+ if (value[value.size()-2] == ',' && value[value.size()-1] == ' ')
+ value.erase(value.size() - 2, 2);
+ fprintf(history_out, "%s: %s\n", tag.c_str(), value.c_str());
+ }
+} /*}}}*/
+// DPkgPM::OpenLog /*{{{*/
bool pkgDPkgPM::OpenLog()
{
string logdir = _config->FindDir("Dir::Log");
if(not FileExists(logdir))
return _error->Error(_("Directory '%s' missing"), logdir.c_str());
+
+ // get current time
+ char timestr[200];
+ time_t t = time(NULL);
+ struct tm *tmp = localtime(&t);
+ strftime(timestr, sizeof(timestr), "%F %T", tmp);
+
+ // open terminal log
string logfile_name = flCombine(logdir,
_config->Find("Dir::Log::Terminal"));
if (!logfile_name.empty())
{
term_out = fopen(logfile_name.c_str(),"a");
chmod(logfile_name.c_str(), 0600);
- // output current time
- char outstr[200];
- time_t t = time(NULL);
- struct tm *tmp = localtime(&t);
- strftime(outstr, sizeof(outstr), "%F %T", tmp);
- fprintf(term_out, "\nLog started: ");
- fprintf(term_out, "%s", outstr);
+ fprintf(term_out, "\n\nLog started: ");
+ fprintf(term_out, "%s", timestr);
fprintf(term_out, "\n");
}
+
+ // write
+ string history_name = flCombine(logdir,
+ _config->Find("Dir::Log::History"));
+ if (!history_name.empty())
+ {
+ history_out = fopen(history_name.c_str(),"a");
+ chmod(history_name.c_str(), 0644);
+ fprintf(history_out, "\nStart-Date: %s\n", timestr);
+ string remove, purge, install, upgrade, downgrade;
+ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
+ {
+ if (Cache[I].NewInstall())
+ install += I.Name() + string(" (") + Cache[I].CandVersion + string("), ");
+ else if (Cache[I].Upgrade())
+ upgrade += I.Name() + string(" (") + Cache[I].CurVersion + string(", ") + Cache[I].CandVersion + string("), ");
+ else if (Cache[I].Downgrade())
+ downgrade += I.Name() + string(" (") + Cache[I].CurVersion + string(", ") + Cache[I].CandVersion + string("), ");
+ else if (Cache[I].Delete())
+ {
+ if ((Cache[I].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge)
+ purge += I.Name() + string(" (") + Cache[I].CurVersion + string("), ");
+ else
+ remove += I.Name() + string(" (") + Cache[I].CurVersion + string("), ");
+ }
+ }
+ WriteHistoryTag("Install", install);
+ WriteHistoryTag("Upgrade", upgrade);
+ WriteHistoryTag("Downgrade",downgrade);
+ WriteHistoryTag("Remove",remove);
+ WriteHistoryTag("Purge",purge);
+ fflush(history_out);
+ }
+
return true;
}
-
+ /*}}}*/
+// DPkg::CloseLog /*{{{*/
bool pkgDPkgPM::CloseLog()
{
+ char timestr[200];
+ time_t t = time(NULL);
+ struct tm *tmp = localtime(&t);
+ strftime(timestr, sizeof(timestr), "%F %T", tmp);
+
if(term_out)
{
- char outstr[200];
- time_t t = time(NULL);
- struct tm *tmp = localtime(&t);
- strftime(outstr, sizeof(outstr), "%F %T", tmp);
fprintf(term_out, "Log ended: ");
- fprintf(term_out, "%s", outstr);
+ fprintf(term_out, "%s", timestr);
fprintf(term_out, "\n");
fclose(term_out);
}
term_out = NULL;
+
+ if(history_out)
+ {
+ if (dpkg_error.size() > 0)
+ fprintf(history_out, "Error: %s\n", dpkg_error.c_str());
+ fprintf(history_out, "End-Date: %s\n", timestr);
+ fclose(history_out);
+ }
+
return true;
}
-
+ /*}}}*/
/*{{{*/
// This implements a racy version of pselect for those architectures
// that don't have a working implementation.
@@ -600,7 +671,6 @@ static int racy_pselect(int nfds, fd_set *readfds, fd_set *writefds,
return retval;
}
/*}}}*/
-
// DPkgPM::Go - Run the sequence /*{{{*/
// ---------------------------------------------------------------------
/* This globs the operations and calls dpkg
@@ -617,9 +687,9 @@ bool pkgDPkgPM::Go(int OutStatusFd)
sigset_t sigmask;
sigset_t original_sigmask;
- unsigned int MaxArgs = _config->FindI("Dpkg::MaxArgs",8*1024);
- unsigned int MaxArgBytes = _config->FindI("Dpkg::MaxArgBytes",32*1024);
- bool NoTriggers = _config->FindB("DPkg::NoTriggers",false);
+ unsigned int const MaxArgs = _config->FindI("Dpkg::MaxArgs",8*1024);
+ unsigned int const MaxArgBytes = _config->FindI("Dpkg::MaxArgBytes",32*1024);
+ bool const NoTriggers = _config->FindB("DPkg::NoTriggers", false);
if (RunScripts("DPkg::Pre-Invoke") == false)
return false;
@@ -627,6 +697,13 @@ bool pkgDPkgPM::Go(int OutStatusFd)
if (RunScriptsWithPkgs("DPkg::Pre-Install-Pkgs") == false)
return false;
+ // support subpressing of triggers processing for special
+ // cases like d-i that runs the triggers handling manually
+ bool const SmartConf = (_config->Find("PackageManager::Configure", "all") != "all");
+ bool const TriggersPending = _config->FindB("DPkg::TriggersPending", false);
+ if (_config->FindB("DPkg::ConfigurePending", SmartConf) == true)
+ List.push_back(Item(Item::ConfigurePending, PkgIterator()));
+
// map the dpkg states to the operations that are performed
// (this is sorted in the same way as Item::Ops)
static const struct DpkgState DpkgStatesOpMap[][7] = {
@@ -640,20 +717,12 @@ bool pkgDPkgPM::Go(int OutStatusFd)
{
{"unpacked",N_("Preparing to configure %s") },
{"half-configured", N_("Configuring %s") },
-#if 0
- {"triggers-awaited", N_("Processing triggers for %s") },
- {"triggers-pending", N_("Processing triggers for %s") },
-#endif
{ "installed", N_("Installed %s")},
{NULL, NULL}
},
// Remove operation
{
{"half-configured", N_("Preparing for removal of %s")},
-#if 0
- {"triggers-awaited", N_("Preparing for removal of %s")},
- {"triggers-pending", N_("Preparing for removal of %s")},
-#endif
{"half-installed", N_("Removing %s")},
{"config-files", N_("Removed %s")},
{NULL, NULL}
@@ -670,16 +739,19 @@ bool pkgDPkgPM::Go(int OutStatusFd)
// that will be [installed|configured|removed|purged] and add
// them to the PackageOps map (the dpkg states it goes through)
// and the PackageOpsTranslations (human readable strings)
- for (vector<Item>::iterator I = List.begin(); I != List.end();I++)
+ for (vector<Item>::const_iterator I = List.begin(); I != List.end();I++)
{
- string name = (*I).Pkg.Name();
+ if((*I).Pkg.end() == true)
+ continue;
+
+ string const name = (*I).Pkg.Name();
PackageOpsDone[name] = 0;
for(int i=0; (DpkgStatesOpMap[(*I).Op][i]).state != NULL; i++)
{
PackageOps[name].push_back(DpkgStatesOpMap[(*I).Op][i]);
PackagesTotal++;
}
- }
+ }
stdin_is_dev_null = false;
@@ -687,19 +759,42 @@ bool pkgDPkgPM::Go(int OutStatusFd)
OpenLog();
// this loop is runs once per operation
- for (vector<Item>::iterator I = List.begin(); I != List.end();)
+ for (vector<Item>::const_iterator I = List.begin(); I != List.end();)
{
- vector<Item>::iterator J = I;
- for (; J != List.end() && J->Op == I->Op; J++);
+ // Do all actions with the same Op in one run
+ vector<Item>::const_iterator J = I;
+ if (TriggersPending == true)
+ for (; J != List.end(); J++)
+ {
+ if (J->Op == I->Op)
+ continue;
+ if (J->Op != Item::TriggersPending)
+ break;
+ vector<Item>::const_iterator T = J + 1;
+ if (T != List.end() && T->Op == I->Op)
+ continue;
+ break;
+ }
+ else
+ for (; J != List.end() && J->Op == I->Op; J++)
+ /* nothing */;
// Generate the argument list
const char *Args[MaxArgs + 50];
+
+ // Now check if we are within the MaxArgs limit
+ //
+ // this code below is problematic, because it may happen that
+ // the argument list is split in a way that A depends on B
+ // and they are in the same "--configure A B" run
+ // - with the split they may now be configured in different
+ // runs
if (J - I > (signed)MaxArgs)
J = I + MaxArgs;
unsigned int n = 0;
unsigned long Size = 0;
- string Tmp = _config->Find("Dir::Bin::dpkg","dpkg");
+ string const Tmp = _config->Find("Dir::Bin::dpkg","dpkg");
Args[n++] = Tmp.c_str();
Size += strlen(Args[n-1]);
@@ -749,11 +844,23 @@ bool pkgDPkgPM::Go(int OutStatusFd)
case Item::Configure:
Args[n++] = "--configure";
- if (NoTriggers)
- Args[n++] = "--no-triggers";
Size += strlen(Args[n-1]);
break;
-
+
+ case Item::ConfigurePending:
+ Args[n++] = "--configure";
+ Size += strlen(Args[n-1]);
+ Args[n++] = "--pending";
+ Size += strlen(Args[n-1]);
+ break;
+
+ case Item::TriggersPending:
+ Args[n++] = "--triggers-only";
+ Size += strlen(Args[n-1]);
+ Args[n++] = "--pending";
+ Size += strlen(Args[n-1]);
+ break;
+
case Item::Install:
Args[n++] = "--unpack";
Size += strlen(Args[n-1]);
@@ -761,7 +868,14 @@ bool pkgDPkgPM::Go(int OutStatusFd)
Size += strlen(Args[n-1]);
break;
}
-
+
+ if (NoTriggers == true && I->Op != Item::TriggersPending &&
+ I->Op != Item::ConfigurePending)
+ {
+ Args[n++] = "--no-triggers";
+ Size += strlen(Args[n-1]);
+ }
+
// Write in the file or package names
if (I->Op == Item::Install)
{
@@ -777,6 +891,8 @@ bool pkgDPkgPM::Go(int OutStatusFd)
{
for (;I != J && Size < MaxArgBytes; I++)
{
+ if((*I).Pkg.end() == true)
+ continue;
Args[n++] = I->Pkg.Name();
Size += strlen(Args[n-1]);
}
@@ -808,32 +924,36 @@ bool pkgDPkgPM::Go(int OutStatusFd)
struct termios tt;
struct winsize win;
- int master;
- int slave;
+ int master = -1;
+ int slave = -1;
- // FIXME: setup sensible signal handling (*ick*)
- tcgetattr(0, &tt);
- ioctl(0, TIOCGWINSZ, (char *)&win);
- if (openpty(&master, &slave, NULL, &tt, &win) < 0)
+ // if tcgetattr does not return zero there was a error
+ // and we do not do any pty magic
+ if (tcgetattr(0, &tt) == 0)
{
- const char *s = _("Can not write log, openpty() "
- "failed (/dev/pts not mounted?)\n");
- fprintf(stderr, "%s",s);
- fprintf(term_out, "%s",s);
- master = slave = -1;
- } else {
- struct termios rtt;
- rtt = tt;
- cfmakeraw(&rtt);
- rtt.c_lflag &= ~ECHO;
- // block SIGTTOU during tcsetattr to prevent a hang if
- // the process is a member of the background process group
- // http://www.opengroup.org/onlinepubs/000095399/functions/tcsetattr.html
- sigemptyset(&sigmask);
- sigaddset(&sigmask, SIGTTOU);
- sigprocmask(SIG_BLOCK,&sigmask, &original_sigmask);
- tcsetattr(0, TCSAFLUSH, &rtt);
- sigprocmask(SIG_SETMASK, &original_sigmask, 0);
+ ioctl(0, TIOCGWINSZ, (char *)&win);
+ if (openpty(&master, &slave, NULL, &tt, &win) < 0)
+ {
+ const char *s = _("Can not write log, openpty() "
+ "failed (/dev/pts not mounted?)\n");
+ fprintf(stderr, "%s",s);
+ if(term_out)
+ fprintf(term_out, "%s",s);
+ master = slave = -1;
+ } else {
+ struct termios rtt;
+ rtt = tt;
+ cfmakeraw(&rtt);
+ rtt.c_lflag &= ~ECHO;
+ // block SIGTTOU during tcsetattr to prevent a hang if
+ // the process is a member of the background process group
+ // http://www.opengroup.org/onlinepubs/000095399/functions/tcsetattr.html
+ sigemptyset(&sigmask);
+ sigaddset(&sigmask, SIGTTOU);
+ sigprocmask(SIG_BLOCK,&sigmask, &original_sigmask);
+ tcsetattr(0, TCSAFLUSH, &rtt);
+ sigprocmask(SIG_SETMASK, &original_sigmask, 0);
+ }
}
// Fork dpkg
@@ -865,6 +985,15 @@ bool pkgDPkgPM::Go(int OutStatusFd)
}
close(fd[0]); // close the read end of the pipe
+ if (_config->FindDir("DPkg::Chroot-Directory","/") != "/")
+ {
+ std::cerr << "Chrooting into "
+ << _config->FindDir("DPkg::Chroot-Directory")
+ << std::endl;
+ if (chroot(_config->FindDir("DPkg::Chroot-Directory","/").c_str()) != 0)
+ _exit(100);
+ }
+
if (chdir(_config->FindDir("DPkg::Run-Directory","/").c_str()) != 0)
_exit(100);
@@ -903,11 +1032,9 @@ bool pkgDPkgPM::Go(int OutStatusFd)
int Status = 0;
// we read from dpkg here
- int _dpkgin = fd[0];
+ int const _dpkgin = fd[0];
close(fd[1]); // close the write end of the pipe
- // the result of the waitpid call
- int res;
if(slave > 0)
close(slave);
@@ -915,6 +1042,8 @@ bool pkgDPkgPM::Go(int OutStatusFd)
sigemptyset(&sigmask);
sigprocmask(SIG_BLOCK,&sigmask,&original_sigmask);
+ // the result of the waitpid call
+ int res;
int select_ret;
while ((res=waitpid(Child,&Status, WNOHANG)) != Child) {
if(res < 0) {
@@ -981,17 +1110,20 @@ bool pkgDPkgPM::Go(int OutStatusFd)
// if it was set to "keep-dpkg-runing" then we won't return
// here but keep the loop going and just report it as a error
// for later
- bool stopOnError = _config->FindB("Dpkg::StopOnError",true);
+ bool const stopOnError = _config->FindB("Dpkg::StopOnError",true);
if(stopOnError)
RunScripts("DPkg::Post-Invoke");
if (WIFSIGNALED(Status) != 0 && WTERMSIG(Status) == SIGSEGV)
- _error->Error("Sub-process %s received a segmentation fault.",Args[0]);
+ strprintf(dpkg_error, "Sub-process %s received a segmentation fault.",Args[0]);
else if (WIFEXITED(Status) != 0)
- _error->Error("Sub-process %s returned an error code (%u)",Args[0],WEXITSTATUS(Status));
+ strprintf(dpkg_error, "Sub-process %s returned an error code (%u)",Args[0],WEXITSTATUS(Status));
else
- _error->Error("Sub-process %s exited unexpectedly",Args[0]);
+ strprintf(dpkg_error, "Sub-process %s exited unexpectedly",Args[0]);
+
+ if(dpkg_error.size() > 0)
+ _error->Error(dpkg_error.c_str());
if(stopOnError)
{
diff --git a/apt-pkg/deb/dpkgpm.h b/apt-pkg/deb/dpkgpm.h
index ebc7e32bf..330c788a2 100644
--- a/apt-pkg/deb/dpkgpm.h
+++ b/apt-pkg/deb/dpkgpm.h
@@ -29,7 +29,9 @@ class pkgDPkgPM : public pkgPackageManager
char dpkgbuf[1024];
int dpkgbuf_pos;
FILE *term_out;
-
+ FILE *history_out;
+ string dpkg_error;
+
protected:
// progress reporting
@@ -53,7 +55,7 @@ class pkgDPkgPM : public pkgPackageManager
struct Item
{
- enum Ops {Install, Configure, Remove, Purge} Op;
+ enum Ops {Install, Configure, Remove, Purge, ConfigurePending, TriggersPending} Op;
string File;
PkgIterator Pkg;
Item(Ops Op,PkgIterator Pkg,string File = "") : Op(Op),
@@ -66,6 +68,7 @@ class pkgDPkgPM : public pkgPackageManager
// Helpers
bool RunScriptsWithPkgs(const char *Cnf);
bool SendV2Pkgs(FILE *F);
+ void WriteHistoryTag(string tag, string value);
// dpkg log
bool OpenLog();
diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc
index 2411bfe89..ec7a5de64 100644
--- a/apt-pkg/depcache.cc
+++ b/apt-pkg/depcache.cc
@@ -15,6 +15,7 @@
#include <apt-pkg/algorithms.h>
#include <apt-pkg/fileutl.h>
+#include <apt-pkg/strutl.h>
#include <apt-pkg/configuration.h>
#include <apt-pkg/pkgsystem.h>
#include <apt-pkg/tagfile.h>
@@ -26,8 +27,8 @@
#include <sys/stat.h>
#include <apti18n.h>
-
-// helper for Install-Recommends-Sections and Never-MarkAuto-Sections
+ /*}}}*/
+// helper for Install-Recommends-Sections and Never-MarkAuto-Sections /*{{{*/
static bool
ConfigValueInSubTree(const char* SubTree, const char *needle)
{
@@ -46,9 +47,8 @@ ConfigValueInSubTree(const char* SubTree, const char *needle)
}
return false;
}
-
-
-pkgDepCache::ActionGroup::ActionGroup(pkgDepCache &cache) :
+ /*}}}*/
+pkgDepCache::ActionGroup::ActionGroup(pkgDepCache &cache) : /*{{{*/
cache(cache), released(false)
{
++cache.group_level;
@@ -76,13 +76,15 @@ pkgDepCache::ActionGroup::~ActionGroup()
{
release();
}
-
+ /*}}}*/
// DepCache::pkgDepCache - Constructors /*{{{*/
// ---------------------------------------------------------------------
/* */
pkgDepCache::pkgDepCache(pkgCache *pCache,Policy *Plcy) :
group_level(0), Cache(pCache), PkgState(0), DepState(0)
{
+ DebugMarker = _config->FindB("Debug::pkgDepCache::Marker", false);
+ DebugAutoInstall = _config->FindB("Debug::pkgDepCache::AutoInstall", false);
delLocalPolicy = 0;
LocalPolicy = Plcy;
if (LocalPolicy == 0)
@@ -127,7 +129,7 @@ bool pkgDepCache::Init(OpProgress *Prog)
int Done = 0;
for (PkgIterator I = PkgBegin(); I.end() != true; I++,Done++)
{
- if (Prog != 0)
+ if (Prog != 0 && Done%20 == 0)
Prog->Progress(Done);
// Find the proper cache slot
@@ -159,8 +161,7 @@ bool pkgDepCache::Init(OpProgress *Prog)
return true;
}
/*}}}*/
-
-bool pkgDepCache::readStateFile(OpProgress *Prog)
+bool pkgDepCache::readStateFile(OpProgress *Prog) /*{{{*/
{
FileFd state_file;
string state = _config->FindDir("Dir::State") + "extended_states";
@@ -174,6 +175,7 @@ bool pkgDepCache::readStateFile(OpProgress *Prog)
pkgTagFile tagfile(&state_file);
pkgTagSection section;
int amt=0;
+ bool debug_autoremove=_config->FindB("Debug::pkgAutoRemove",false);
while(tagfile.Step(section)) {
string pkgname = section.FindS("Package");
pkgCache::PkgIterator pkg=Cache->FindPkg(pkgname);
@@ -183,7 +185,7 @@ bool pkgDepCache::readStateFile(OpProgress *Prog)
short reason = section.FindI("Auto-Installed", 0);
if(reason > 0)
PkgState[pkg->ID].Flags |= Flag::Auto;
- if(_config->FindB("Debug::pkgAutoRemove",false))
+ if(debug_autoremove)
std::cout << "Auto-Installed : " << pkgname << std::endl;
amt+=section.size();
if(Prog != NULL)
@@ -198,10 +200,12 @@ bool pkgDepCache::readStateFile(OpProgress *Prog)
return true;
}
-
-bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly)
+ /*}}}*/
+bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly) /*{{{*/
{
- if(_config->FindB("Debug::pkgAutoRemove",false))
+ bool debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false);
+
+ if(debug_autoremove)
std::clog << "pkgDepCache::writeStateFile()" << std::endl;
FileFd StateFile;
@@ -239,7 +243,7 @@ bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly)
continue;
bool newAuto = (PkgState[pkg->ID].Flags & Flag::Auto);
if(_config->FindB("Debug::pkgAutoRemove",false))
- std::clog << "Update exisiting AutoInstall info: "
+ std::clog << "Update existing AutoInstall info: "
<< pkg.Name() << std::endl;
TFRewriteData rewrite[2];
rewrite[0].Tag = "Auto-Installed";
@@ -256,14 +260,14 @@ bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly)
for(pkgCache::PkgIterator pkg=Cache->PkgBegin(); !pkg.end(); pkg++) {
if(PkgState[pkg->ID].Flags & Flag::Auto) {
if (pkgs_seen.find(pkg.Name()) != pkgs_seen.end()) {
- if(_config->FindB("Debug::pkgAutoRemove",false))
+ if(debug_autoremove)
std::clog << "Skipping already written " << pkg.Name() << std::endl;
continue;
}
// skip not installed ones if requested
if(InstalledOnly && pkg->CurrentVer == 0)
continue;
- if(_config->FindB("Debug::pkgAutoRemove",false))
+ if(debug_autoremove)
std::clog << "Writing new AutoInstall: "
<< pkg.Name() << std::endl;
ostr.str(string(""));
@@ -281,7 +285,7 @@ bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly)
return true;
}
-
+ /*}}}*/
// DepCache::CheckDep - Checks a single dependency /*{{{*/
// ---------------------------------------------------------------------
/* This first checks the dependency against the main target package and
@@ -699,13 +703,12 @@ void pkgDepCache::Update(PkgIterator const &Pkg)
P.end() != true; P++)
Update(P.ParentPkg().RevDependsList());
}
-
/*}}}*/
-
// DepCache::MarkKeep - Put the package in the keep state /*{{{*/
// ---------------------------------------------------------------------
/* */
-void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser)
+void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser,
+ unsigned long Depth)
{
// Simplifies other routines.
if (Pkg.end() == true)
@@ -746,6 +749,9 @@ void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser)
P.Flags &= ~Flag::Auto;
#endif
+ if (DebugMarker == true)
+ std::clog << OutputInDepth(Depth) << "MarkKeep " << Pkg << " FU=" << FromUser << std::endl;
+
RemoveSizes(Pkg);
RemoveStates(Pkg);
@@ -765,7 +771,8 @@ void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser)
// DepCache::MarkDelete - Put the package in the delete state /*{{{*/
// ---------------------------------------------------------------------
/* */
-void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge)
+void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge,
+ unsigned long Depth, bool FromUser)
{
// Simplifies other routines.
if (Pkg.end() == true)
@@ -787,6 +794,13 @@ void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge)
if (Pkg->VersionList == 0)
return;
+ // check if we are allowed to install the package
+ if (IsDeleteOk(Pkg,rPurge,Depth,FromUser) == false)
+ return;
+
+ if (DebugMarker == true)
+ std::clog << OutputInDepth(Depth) << "MarkDelete " << Pkg << " FU=" << FromUser << std::endl;
+
RemoveSizes(Pkg);
RemoveStates(Pkg);
@@ -801,6 +815,23 @@ void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge)
AddSizes(Pkg);
}
/*}}}*/
+// DepCache::IsDeleteOk - check if it is ok to remove this package /*{{{*/
+// ---------------------------------------------------------------------
+/* The default implementation just honors dpkg hold
+ But an application using this library can override this method
+ to control the MarkDelete behaviour */
+bool pkgDepCache::IsDeleteOk(PkgIterator const &Pkg,bool rPurge,
+ unsigned long Depth, bool FromUser)
+{
+ if (FromUser == false && Pkg->SelectedState == pkgCache::State::Hold && _config->FindB("APT::Ignore-Hold",false) == false)
+ {
+ if (DebugMarker == true)
+ std::clog << OutputInDepth(Depth) << "Hold prevents MarkDelete of " << Pkg << " FU=" << FromUser << std::endl;
+ return false;
+ }
+ return true;
+}
+ /*}}}*/
// DepCache::MarkInstall - Put the package in the install state /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -826,7 +857,7 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
P.CandidateVer == (Version *)Pkg.CurrentVer()))
{
if (P.CandidateVer == (Version *)Pkg.CurrentVer() && P.InstallVer == 0)
- MarkKeep(Pkg, false, FromUser);
+ MarkKeep(Pkg, false, FromUser, Depth+1);
return;
}
@@ -836,6 +867,11 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
// We dont even try to install virtual packages..
if (Pkg->VersionList == 0)
return;
+
+ // check if we are allowed to install the package
+ if (IsInstallOk(Pkg,AutoInst,Depth,FromUser) == false)
+ return;
+
/* Target the candidate version and remove the autoflag. We reset the
autoflag below if this was called recursively. Otherwise the user
should have the ability to de-auto a package by changing its state */
@@ -864,10 +900,13 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
AddStates(Pkg);
Update(Pkg);
AddSizes(Pkg);
-
+
if (AutoInst == false)
return;
+ if (DebugMarker == true)
+ std::clog << OutputInDepth(Depth) << "MarkInstall " << Pkg << " FU=" << FromUser << std::endl;
+
DepIterator Dep = P.InstVerIter(*this).DependsList();
for (; Dep.end() != true;)
{
@@ -937,12 +976,12 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
}
}
if(isNewImportantDep)
- if(_config->FindB("Debug::pkgDepCache::AutoInstall",false) == true)
- std::clog << "new important dependency: "
+ if(DebugAutoInstall == true)
+ std::clog << OutputInDepth(Depth) << "new important dependency: "
<< Start.TargetPkg().Name() << std::endl;
if(isPreviouslySatisfiedImportantDep)
- if(_config->FindB("Debug::pkgDepCache::AutoInstall", false) == true)
- std::clog << "previously satisfied important dependency on "
+ if(DebugAutoInstall == true)
+ std::clog << OutputInDepth(Depth) << "previously satisfied important dependency on "
<< Start.TargetPkg().Name() << std::endl;
// skip important deps if the package is already installed
@@ -991,17 +1030,18 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
}
}
- if (InstPkg.end() == false)
+ if (InstPkg.end() == false)
{
- if(_config->FindB("Debug::pkgDepCache::AutoInstall",false) == true)
- std::clog << "Installing " << InstPkg.Name()
- << " as dep of " << Pkg.Name()
+ if(DebugAutoInstall == true)
+ std::clog << OutputInDepth(Depth) << "Installing " << InstPkg.Name()
+ << " as " << Start.DepType() << " of " << Pkg.Name()
<< std::endl;
// now check if we should consider it a automatic dependency or not
if(Pkg.Section() && ConfigValueInSubTree("APT::Never-MarkAuto-Sections", Pkg.Section()))
{
- if(_config->FindB("Debug::pkgDepCache::AutoInstall",false) == true)
- std::clog << "Setting NOT as auto-installed (direct dep of pkg in APT::Never-MarkAuto-Sections)" << std::endl;
+ if(DebugAutoInstall == true)
+ std::clog << OutputInDepth(Depth) << "Setting NOT as auto-installed (direct "
+ << Start.DepType() << " of pkg in APT::Never-MarkAuto-Sections)" << std::endl;
MarkInstall(InstPkg,true,Depth + 1, true);
}
else
@@ -1028,16 +1068,32 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
PkgIterator Pkg = Ver.ParentPkg();
if (Start->Type != Dep::DpkgBreaks)
- MarkDelete(Pkg);
- else
- if (PkgState[Pkg->ID].CandidateVer != *I)
- MarkInstall(Pkg,true,Depth + 1, false, ForceImportantDeps);
+ MarkDelete(Pkg,false,Depth + 1, false);
+ else if (PkgState[Pkg->ID].CandidateVer != *I)
+ MarkInstall(Pkg,true,Depth + 1, false, ForceImportantDeps);
}
continue;
}
}
}
/*}}}*/
+// DepCache::IsInstallOk - check if it is ok to install this package /*{{{*/
+// ---------------------------------------------------------------------
+/* The default implementation just honors dpkg hold
+ But an application using this library can override this method
+ to control the MarkInstall behaviour */
+bool pkgDepCache::IsInstallOk(PkgIterator const &Pkg,bool AutoInst,
+ unsigned long Depth, bool FromUser)
+{
+ if (FromUser == false && Pkg->SelectedState == pkgCache::State::Hold && _config->FindB("APT::Ignore-Hold",false) == false)
+ {
+ if (DebugMarker == true)
+ std::clog << OutputInDepth(Depth) << "Hold prevents MarkInstall of " << Pkg << " FU=" << FromUser << std::endl;
+ return false;
+ }
+ return true;
+}
+ /*}}}*/
// DepCache::SetReInstall - Set the reinstallation flag /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -1137,7 +1193,6 @@ const char *pkgDepCache::StateCache::StripEpoch(const char *Ver)
return Ver;
}
/*}}}*/
-
// Policy::GetCandidateVer - Returns the Candidate install version /*{{{*/
// ---------------------------------------------------------------------
/* The default just returns the highest available version that is not
@@ -1174,7 +1229,6 @@ pkgCache::VerIterator pkgDepCache::Policy::GetCandidateVer(PkgIterator Pkg)
return Last;
}
/*}}}*/
-
// Policy::IsImportantDep - True if the dependency is important /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -1200,8 +1254,7 @@ bool pkgDepCache::Policy::IsImportantDep(DepIterator Dep)
return false;
}
/*}}}*/
-
-pkgDepCache::DefaultRootSetFunc::DefaultRootSetFunc()
+pkgDepCache::DefaultRootSetFunc::DefaultRootSetFunc() /*{{{*/
: constructedSuccessfully(false)
{
Configuration::Item const *Opts;
@@ -1230,8 +1283,8 @@ pkgDepCache::DefaultRootSetFunc::DefaultRootSetFunc()
constructedSuccessfully = true;
}
-
-pkgDepCache::DefaultRootSetFunc::~DefaultRootSetFunc()
+ /*}}}*/
+pkgDepCache::DefaultRootSetFunc::~DefaultRootSetFunc() /*{{{*/
{
for(unsigned int i = 0; i < rootSetRegexp.size(); i++)
{
@@ -1239,9 +1292,8 @@ pkgDepCache::DefaultRootSetFunc::~DefaultRootSetFunc()
delete rootSetRegexp[i];
}
}
-
-
-bool pkgDepCache::DefaultRootSetFunc::InRootSet(const pkgCache::PkgIterator &pkg)
+ /*}}}*/
+bool pkgDepCache::DefaultRootSetFunc::InRootSet(const pkgCache::PkgIterator &pkg) /*{{{*/
{
for(unsigned int i = 0; i < rootSetRegexp.size(); i++)
if (regexec(rootSetRegexp[i], pkg.Name(), 0, 0, 0) == 0)
@@ -1249,8 +1301,8 @@ bool pkgDepCache::DefaultRootSetFunc::InRootSet(const pkgCache::PkgIterator &pkg
return false;
}
-
-pkgDepCache::InRootSetFunc *pkgDepCache::GetRootSetFunc()
+ /*}}}*/
+pkgDepCache::InRootSetFunc *pkgDepCache::GetRootSetFunc() /*{{{*/
{
DefaultRootSetFunc *f = new DefaultRootSetFunc;
if(f->wasConstructedSuccessfully())
@@ -1261,7 +1313,7 @@ pkgDepCache::InRootSetFunc *pkgDepCache::GetRootSetFunc()
return NULL;
}
}
-
+ /*}}}*/
bool pkgDepCache::MarkFollowsRecommends()
{
return _config->FindB("APT::AutoRemove::RecommendsImportant", true);
@@ -1272,11 +1324,12 @@ bool pkgDepCache::MarkFollowsSuggests()
return _config->FindB("APT::AutoRemove::SuggestsImportant", false);
}
-// the main mark algorithm
+// pkgDepCache::MarkRequired - the main mark algorithm /*{{{*/
bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc)
{
bool follow_recommends;
bool follow_suggests;
+ bool debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false);
// init the states
for(PkgIterator p = PkgBegin(); !p.end(); ++p)
@@ -1285,8 +1338,7 @@ bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc)
PkgState[p->ID].Garbage = false;
// debug output
- if(_config->FindB("Debug::pkgAutoRemove",false)
- && PkgState[p->ID].Flags & Flag::Auto)
+ if(debug_autoremove && PkgState[p->ID].Flags & Flag::Auto)
std::clog << "AutoDep: " << p.Name() << std::endl;
}
@@ -1317,8 +1369,8 @@ bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc)
return true;
}
-
-// mark a single package in Mark-and-Sweep
+ /*}}}*/
+// MarkPackage - mark a single package in Mark-and-Sweep /*{{{*/
void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg,
const pkgCache::VerIterator &ver,
bool follow_recommends,
@@ -1357,7 +1409,9 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg,
if(state.Marked)
return;
- if(_config->FindB("Debug::pkgAutoRemove",false))
+ bool debug_autoremove = _config->FindB("Debug::pkgAutoRemove", false);
+
+ if(debug_autoremove)
{
std::clog << "Marking: " << pkg.Name();
if(!ver.end())
@@ -1388,7 +1442,7 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg,
{
if(_system->VS->CheckDep(V.VerStr(), d->CompareOp, d.TargetVer()))
{
- if(_config->FindB("Debug::pkgAutoRemove",false))
+ if(debug_autoremove)
{
std::clog << "Following dep: " << d.ParentPkg().Name()
<< " " << d.ParentVer().VerStr() << " "
@@ -1412,7 +1466,7 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg,
if(_system->VS->CheckDep(prv.ProvideVersion(), d->CompareOp,
d.TargetVer()))
{
- if(_config->FindB("Debug::pkgAutoRemove",false))
+ if(debug_autoremove)
{
std::clog << "Following dep: " << d.ParentPkg().Name()
<< " " << d.ParentVer().VerStr() << " "
@@ -1437,12 +1491,14 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg,
}
}
}
-
-bool pkgDepCache::Sweep()
+ /*}}}*/
+bool pkgDepCache::Sweep() /*{{{*/
{
+ bool debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false);
+
// do the sweep
for(PkgIterator p=PkgBegin(); !p.end(); ++p)
- {
+ {
StateCache &state=PkgState[p->ID];
// skip required packages
@@ -1454,10 +1510,11 @@ bool pkgDepCache::Sweep()
if(!state.Marked && (!p.CurrentVer().end() || state.Install()))
{
state.Garbage=true;
- if(_config->FindB("Debug::pkgAutoRemove",false))
+ if(debug_autoremove)
std::cout << "Garbage: " << p.Name() << std::endl;
}
}
return true;
}
+ /*}}}*/
diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h
index f41ad17e9..0306861a1 100644
--- a/apt-pkg/depcache.h
+++ b/apt-pkg/depcache.h
@@ -294,7 +294,10 @@ class pkgDepCache : protected pkgCache::Namespace
unsigned long iBrokenCount;
unsigned long iPolicyBrokenCount;
unsigned long iBadCount;
-
+
+ bool DebugMarker;
+ bool DebugAutoInstall;
+
Policy *delLocalPolicy; // For memory clean up..
Policy *LocalPolicy;
@@ -387,18 +390,58 @@ class pkgDepCache : protected pkgCache::Namespace
*/
// @{
void MarkKeep(PkgIterator const &Pkg, bool Soft = false,
- bool FromUser = true);
- void MarkDelete(PkgIterator const &Pkg,bool Purge = false);
+ bool FromUser = true, unsigned long Depth = 0);
+ void MarkDelete(PkgIterator const &Pkg, bool Purge = false,
+ unsigned long Depth = 0, bool FromUser = true);
void MarkInstall(PkgIterator const &Pkg,bool AutoInst = true,
unsigned long Depth = 0, bool FromUser = true,
bool ForceImportantDeps = false);
+
void SetReInstall(PkgIterator const &Pkg,bool To);
void SetCandidateVersion(VerIterator TargetVer);
/** Set the "is automatically installed" flag of Pkg. */
void MarkAuto(const PkgIterator &Pkg, bool Auto);
// @}
-
+
+ /** \return \b true if it's OK for MarkInstall to install
+ * the given package.
+ *
+ * See the default implementation for a simple example how this
+ * method can be used.
+ * Overriding implementations should use the hold-state-flag to cache
+ * results from previous checks of this package - also it should
+ * be used if the default resolver implementation is also used to
+ * ensure that these packages are handled like "normal" dpkg holds.
+ *
+ * The parameters are the same as in the calling MarkInstall:
+ * \param Pkg the package that MarkInstall wants to install.
+ * \param AutoInst needs a previous MarkInstall this package?
+ * \param Depth recursive deep of this Marker call
+ * \param FromUser was the install requested by the user?
+ */
+ virtual bool IsInstallOk(const PkgIterator &Pkg,bool AutoInst = true,
+ unsigned long Depth = 0, bool FromUser = true);
+
+ /** \return \b true if it's OK for MarkDelete to remove
+ * the given package.
+ *
+ * See the default implementation for a simple example how this
+ * method can be used.
+ * Overriding implementations should use the hold-state-flag to cache
+ * results from previous checks of this package - also it should
+ * be used if the default resolver implementation is also used to
+ * ensure that these packages are handled like "normal" dpkg holds.
+ *
+ * The parameters are the same as in the calling MarkDelete:
+ * \param Pkg the package that MarkDelete wants to remove.
+ * \param Purge should we purge instead of "only" remove?
+ * \param Depth recursive deep of this Marker call
+ * \param FromUser was the remove requested by the user?
+ */
+ virtual bool IsDeleteOk(const PkgIterator &Pkg,bool Purge = false,
+ unsigned long Depth = 0, bool FromUser = true);
+
// This is for debuging
void Update(OpProgress *Prog = 0);
diff --git a/apt-pkg/indexcopy.cc b/apt-pkg/indexcopy.cc
index 5a92c79b7..57c9f95ca 100644
--- a/apt-pkg/indexcopy.cc
+++ b/apt-pkg/indexcopy.cc
@@ -527,19 +527,19 @@ bool SigVerify::Verify(string prefix, string file, indexRecords *MetaIndex)
// (non-existing files are not considered a error)
if(!FileExists(prefix+file))
{
- _error->Warning("Skipping non-exisiting file %s", string(prefix+file).c_str());
+ _error->Warning(_("Skipping nonexistent file %s"), string(prefix+file).c_str());
return true;
}
if (!Record)
{
- _error->Warning("Can't find authentication record for: %s",file.c_str());
+ _error->Warning(_("Can't find authentication record for: %s"), file.c_str());
return false;
}
if (!Record->Hash.VerifyFile(prefix+file))
{
- _error->Warning("Hash mismatch for: %s",file.c_str());
+ _error->Warning(_("Hash mismatch for: %s"),file.c_str());
return false;
}
@@ -551,8 +551,8 @@ bool SigVerify::Verify(string prefix, string file, indexRecords *MetaIndex)
return true;
}
-
-bool SigVerify::CopyMetaIndex(string CDROM, string CDName,
+ /*}}}*/
+bool SigVerify::CopyMetaIndex(string CDROM, string CDName, /*{{{*/
string prefix, string file)
{
char S[400];
@@ -572,8 +572,8 @@ bool SigVerify::CopyMetaIndex(string CDROM, string CDName,
return true;
}
-
-bool SigVerify::CopyAndVerify(string CDROM,string Name,vector<string> &SigList,
+ /*}}}*/
+bool SigVerify::CopyAndVerify(string CDROM,string Name,vector<string> &SigList, /*{{{*/
vector<string> PkgList,vector<string> SrcList)
{
if (SigList.size() == 0)
@@ -592,7 +592,10 @@ bool SigVerify::CopyAndVerify(string CDROM,string Name,vector<string> &SigList,
// a Release.gpg without a Release should never happen
if(!FileExists(*I+"Release"))
+ {
+ delete MetaIndex;
continue;
+ }
// verify the gpg signature of "Release"
@@ -675,10 +678,9 @@ bool SigVerify::CopyAndVerify(string CDROM,string Name,vector<string> &SigList,
return true;
}
-
-
-bool TranslationsCopy::CopyTranslations(string CDROM,string Name,vector<string> &List,
- pkgCdromStatus *log)
+ /*}}}*/
+bool TranslationsCopy::CopyTranslations(string CDROM,string Name, /*{{{*/
+ vector<string> &List, pkgCdromStatus *log)
{
OpProgress *Progress = NULL;
if (List.size() == 0)
@@ -850,3 +852,4 @@ bool TranslationsCopy::CopyTranslations(string CDROM,string Name,vector<string>
return true;
}
+ /*}}}*/
diff --git a/apt-pkg/indexcopy.h b/apt-pkg/indexcopy.h
index 7778ae595..9e5ad4e43 100644
--- a/apt-pkg/indexcopy.h
+++ b/apt-pkg/indexcopy.h
@@ -22,7 +22,7 @@ class FileFd;
class indexRecords;
class pkgCdromStatus;
-class IndexCopy
+class IndexCopy /*{{{*/
{
protected:
@@ -45,8 +45,8 @@ class IndexCopy
pkgCdromStatus *log);
virtual ~IndexCopy() {};
};
-
-class PackageCopy : public IndexCopy
+ /*}}}*/
+class PackageCopy : public IndexCopy /*{{{*/
{
protected:
@@ -57,8 +57,8 @@ class PackageCopy : public IndexCopy
public:
};
-
-class SourceCopy : public IndexCopy
+ /*}}}*/
+class SourceCopy : public IndexCopy /*{{{*/
{
protected:
@@ -69,8 +69,8 @@ class SourceCopy : public IndexCopy
public:
};
-
-class TranslationsCopy
+ /*}}}*/
+class TranslationsCopy /*{{{*/
{
protected:
pkgTagSection *Section;
@@ -79,9 +79,8 @@ class TranslationsCopy
bool CopyTranslations(string CDROM,string Name,vector<string> &List,
pkgCdromStatus *log);
};
-
-
-class SigVerify
+ /*}}}*/
+class SigVerify /*{{{*/
{
bool Verify(string prefix,string file, indexRecords *records);
bool CopyMetaIndex(string CDROM, string CDName,
@@ -91,7 +90,6 @@ class SigVerify
bool CopyAndVerify(string CDROM,string Name,vector<string> &SigList,
vector<string> PkgList,vector<string> SrcList);
};
-
-
+ /*}}}*/
#endif
diff --git a/apt-pkg/indexfile.cc b/apt-pkg/indexfile.cc
index b38596143..08f71feb0 100644
--- a/apt-pkg/indexfile.cc
+++ b/apt-pkg/indexfile.cc
@@ -41,7 +41,6 @@ pkgIndexFile::Type *pkgIndexFile::Type::GetType(const char *Type)
return 0;
}
/*}}}*/
-
// IndexFile::ArchiveInfo - Stub /*{{{*/
// ---------------------------------------------------------------------
/* */
diff --git a/apt-pkg/indexrecords.cc b/apt-pkg/indexrecords.cc
index ab208e246..1fc27b1a1 100644
--- a/apt-pkg/indexrecords.cc
+++ b/apt-pkg/indexrecords.cc
@@ -9,7 +9,7 @@
#include <apt-pkg/strutl.h>
#include <apti18n.h>
#include <sys/stat.h>
-
+ /*}}}*/
string indexRecords::GetDist() const
{
return this->Dist;
@@ -31,7 +31,7 @@ const indexRecords::checkSum *indexRecords::Lookup(const string MetaKey)
return Entries[MetaKey];
}
-bool indexRecords::Load(const string Filename)
+bool indexRecords::Load(const string Filename) /*{{{*/
{
FileFd Fd(Filename, FileFd::ReadOnly);
pkgTagFile TagFile(&Fd, Fd.Size() + 256); // XXX
@@ -85,8 +85,8 @@ bool indexRecords::Load(const string Filename)
string Strdate = Section.FindS("Date"); // FIXME: verify this somehow?
return true;
}
-
-vector<string> indexRecords::MetaKeys()
+ /*}}}*/
+vector<string> indexRecords::MetaKeys() /*{{{*/
{
std::vector<std::string> keys;
std::map<string,checkSum *>::iterator I = Entries.begin();
@@ -96,8 +96,8 @@ vector<string> indexRecords::MetaKeys()
}
return keys;
}
-
-bool indexRecords::parseSumData(const char *&Start, const char *End,
+ /*}}}*/
+bool indexRecords::parseSumData(const char *&Start, const char *End, /*{{{*/
string &Name, string &Hash, size_t &Size)
{
Name = "";
@@ -154,7 +154,7 @@ bool indexRecords::parseSumData(const char *&Start, const char *End,
Start = EntryEnd; //prepare for the next round
return true;
}
-
+ /*}}}*/
indexRecords::indexRecords()
{
}
diff --git a/apt-pkg/init.cc b/apt-pkg/init.cc
index 338bef66c..2544b8025 100644
--- a/apt-pkg/init.cc
+++ b/apt-pkg/init.cc
@@ -65,13 +65,16 @@ bool pkgInitConfig(Configuration &Cnf)
Cnf.Set("Dir::Etc::vendorlist","vendors.list");
Cnf.Set("Dir::Etc::vendorparts","vendors.list.d");
Cnf.Set("Dir::Etc::main","apt.conf");
+ Cnf.Set("Dir::ETc::netrc", "auth.conf");
Cnf.Set("Dir::Etc::parts","apt.conf.d");
Cnf.Set("Dir::Etc::preferences","preferences");
+ Cnf.Set("Dir::Etc::preferencesparts","preferences.d");
Cnf.Set("Dir::Bin::methods","/usr/lib/apt/methods");
// State
Cnf.Set("Dir::Log","var/log/apt");
Cnf.Set("Dir::Log::Terminal","term.log");
+ Cnf.Set("Dir::Log::History","history.log");
// Translation
Cnf.Set("APT::Acquire::Translation", "environment");
@@ -80,22 +83,29 @@ bool pkgInitConfig(Configuration &Cnf)
// Read an alternate config file
const char *Cfg = getenv("APT_CONFIG");
- if (Cfg != 0 && FileExists(Cfg) == true)
- Res &= ReadConfigFile(Cnf,Cfg);
-
+ if (Cfg != 0)
+ {
+ if (FileExists(Cfg) == true)
+ Res &= ReadConfigFile(Cnf,Cfg);
+ else
+ _error->WarningE("FileExists",_("Unable to read %s"),Cfg);
+ }
+
// Read the configuration parts dir
string Parts = Cnf.FindDir("Dir::Etc::parts");
if (FileExists(Parts) == true)
Res &= ReadConfigDir(Cnf,Parts);
-
+ else
+ _error->WarningE("FileExists",_("Unable to read %s"),Parts.c_str());
+
// Read the main config file
string FName = Cnf.FindFile("Dir::Etc::main");
if (FileExists(FName) == true)
Res &= ReadConfigFile(Cnf,FName);
-
+
if (Res == false)
return false;
-
+
if (Cnf.FindB("Debug::pkgInitConfig",false) == true)
Cnf.Dump();
diff --git a/apt-pkg/init.h b/apt-pkg/init.h
index 6d8693be9..f0757f644 100644
--- a/apt-pkg/init.h
+++ b/apt-pkg/init.h
@@ -16,9 +16,13 @@
#include <apt-pkg/configuration.h>
#include <apt-pkg/pkgsystem.h>
-// See the makefile
+// These lines are extracted by the makefiles and the buildsystem
+// Increasing MAJOR or MINOR results in the need of recompiling all
+// reverse-dependencies of libapt-pkg against the new SONAME.
+// Non-ABI-Breaks should only increase RELEASE number.
+// See also buildlib/libversion.mak
#define APT_PKG_MAJOR 4
-#define APT_PKG_MINOR 6
+#define APT_PKG_MINOR 8
#define APT_PKG_RELEASE 0
extern const char *pkgVersion;
diff --git a/apt-pkg/makefile b/apt-pkg/makefile
index 387151baf..3d6209658 100644
--- a/apt-pkg/makefile
+++ b/apt-pkg/makefile
@@ -9,23 +9,22 @@ HEADER_TARGETDIRS = apt-pkg
# Bring in the default rules
include ../buildlib/defaults.mak
-# The library name, don't forget to update init.h and the copy in
-# methods/makefile - FIXME
+# The library name and version (indirectly used from init.h)
+include ../buildlib/libversion.mak
LIBRARY=apt-pkg
-LIBEXT=$(GLIBC_VER)$(LIBSTDCPP_VER)
-MAJOR=4.7
-MINOR=0
+MAJOR=$(LIBAPTPKG_MAJOR)
+MINOR=$(LIBAPTPKG_RELEASE)
SLIBS=$(PTHREADLIB) $(INTLLIBS) -lutil -ldl
-APT_DOMAIN:=libapt-pkg$(MAJOR)
+APT_DOMAIN:=libapt-pkg$(LIBAPTPKG_MAJOR)
# Source code for the contributed non-core things
SOURCE = contrib/mmap.cc contrib/error.cc contrib/strutl.cc \
contrib/configuration.cc contrib/progress.cc contrib/cmndline.cc \
contrib/md5.cc contrib/sha1.cc contrib/sha256.cc contrib/hashes.cc \
- contrib/cdromutl.cc contrib/crc-16.cc \
+ contrib/cdromutl.cc contrib/crc-16.cc contrib/netrc.cc \
contrib/fileutl.cc
-HEADERS = mmap.h error.h configuration.h fileutl.h cmndline.h \
- md5.h crc-16.h cdromutl.h strutl.h sptr.h sha1.h sha256.h hashes.h
+HEADERS = mmap.h error.h configuration.h fileutl.h cmndline.h netrc.h\
+ md5.h crc-16.h cdromutl.h strutl.h sptr.h sha1.h sha256.h hashes.h
# Source code for the core main library
SOURCE+= pkgcache.cc version.cc depcache.cc \
@@ -34,14 +33,15 @@ SOURCE+= pkgcache.cc version.cc depcache.cc \
acquire-worker.cc acquire-method.cc init.cc clean.cc \
srcrecords.cc cachefile.cc versionmatch.cc policy.cc \
pkgsystem.cc indexfile.cc pkgcachegen.cc acquire-item.cc \
- indexrecords.cc vendor.cc vendorlist.cc cdrom.cc indexcopy.cc
+ indexrecords.cc vendor.cc vendorlist.cc cdrom.cc indexcopy.cc \
+ aptconfiguration.cc
HEADERS+= algorithms.h depcache.h pkgcachegen.h cacheiterators.h \
orderlist.h sourcelist.h packagemanager.h tagfile.h \
init.h pkgcache.h version.h progress.h pkgrecords.h \
acquire.h acquire-worker.h acquire-item.h acquire-method.h \
clean.h srcrecords.h cachefile.h versionmatch.h policy.h \
pkgsystem.h indexfile.h metaindex.h indexrecords.h vendor.h \
- vendorlist.h cdrom.h indexcopy.h
+ vendorlist.h cdrom.h indexcopy.h aptconfiguration.h
# Source code for the debian specific components
# In theory the deb headers do not need to be exported..
diff --git a/apt-pkg/metaindex.h b/apt-pkg/metaindex.h
index 2b87d7da9..779b6ab14 100644
--- a/apt-pkg/metaindex.h
+++ b/apt-pkg/metaindex.h
@@ -39,7 +39,13 @@ class metaIndex
virtual vector<pkgIndexFile *> *GetIndexFiles() = 0;
virtual bool IsTrusted() const = 0;
- virtual ~metaIndex() {};
+ virtual ~metaIndex() {
+ if (Indexes == 0)
+ return;
+ for (vector<pkgIndexFile *>::iterator I = (*Indexes).begin(); I != (*Indexes).end(); ++I)
+ delete *I;
+ delete Indexes;
+ }
};
#endif
diff --git a/apt-pkg/orderlist.cc b/apt-pkg/orderlist.cc
index ca18f1d75..0ee2e2bc8 100644
--- a/apt-pkg/orderlist.cc
+++ b/apt-pkg/orderlist.cc
@@ -129,7 +129,6 @@ bool pkgOrderList::IsMissing(PkgIterator Pkg)
return true;
}
/*}}}*/
-
// OrderList::DoRun - Does an order run /*{{{*/
// ---------------------------------------------------------------------
/* The caller is expeted to have setup the desired probe state */
@@ -175,22 +174,35 @@ bool pkgOrderList::DoRun()
bool pkgOrderList::OrderCritical()
{
FileList = 0;
-
- Primary = &pkgOrderList::DepUnPackPre;
+
+ Primary = &pkgOrderList::DepUnPackPreD;
Secondary = 0;
RevDepends = 0;
Remove = 0;
LoopCount = 0;
-
+
// Sort
Me = this;
- qsort(List,End - List,sizeof(*List),&OrderCompareB);
-
+ qsort(List,End - List,sizeof(*List),&OrderCompareB);
+
if (DoRun() == false)
return false;
-
+
if (LoopCount != 0)
return _error->Error("Fatal, predepends looping detected");
+
+ if (Debug == true)
+ {
+ clog << "** Critical Unpack ordering done" << endl;
+
+ for (iterator I = List; I != End; I++)
+ {
+ PkgIterator P(Cache,*I);
+ if (IsNow(P) == true)
+ clog << " " << P.Name() << ' ' << IsMissing(P) << ',' << IsFlag(P,After) << endl;
+ }
+ }
+
return true;
}
/*}}}*/
@@ -206,7 +218,7 @@ bool pkgOrderList::OrderUnpack(string *FileList)
if (FileList != 0)
{
WipeFlags(After);
-
+
// Set the inlist flag
for (iterator I = List; I != End; I++)
{
@@ -215,7 +227,7 @@ bool pkgOrderList::OrderUnpack(string *FileList)
Flag(*I,After);
}
}
-
+
Primary = &pkgOrderList::DepUnPackCrit;
Secondary = &pkgOrderList::DepConfigure;
RevDepends = &pkgOrderList::DepUnPackDep;
@@ -230,7 +242,7 @@ bool pkgOrderList::OrderUnpack(string *FileList)
clog << "** Pass A" << endl;
if (DoRun() == false)
return false;
-
+
if (Debug == true)
clog << "** Pass B" << endl;
Secondary = 0;
@@ -244,7 +256,7 @@ bool pkgOrderList::OrderUnpack(string *FileList)
Remove = 0; // Otherwise the libreadline remove problem occures
if (DoRun() == false)
return false;
-
+
if (Debug == true)
clog << "** Pass D" << endl;
LoopCount = 0;
@@ -260,9 +272,9 @@ bool pkgOrderList::OrderUnpack(string *FileList)
{
PkgIterator P(Cache,*I);
if (IsNow(P) == true)
- clog << P.Name() << ' ' << IsMissing(P) << ',' << IsFlag(P,After) << endl;
+ clog << " " << P.Name() << ' ' << IsMissing(P) << ',' << IsFlag(P,After) << endl;
}
- }
+ }
return true;
}
@@ -282,35 +294,40 @@ bool pkgOrderList::OrderConfigure()
return DoRun();
}
/*}}}*/
-
// OrderList::Score - Score the package for sorting /*{{{*/
// ---------------------------------------------------------------------
/* Higher scores order earlier */
int pkgOrderList::Score(PkgIterator Pkg)
{
+ static int const ScoreDelete = _config->FindI("OrderList::Score::Delete", 500);
+
// Removal is always done first
if (Cache[Pkg].Delete() == true)
- return 200;
-
+ return ScoreDelete;
+
// This should never happen..
if (Cache[Pkg].InstVerIter(Cache).end() == true)
return -1;
-
+
+ static int const ScoreEssential = _config->FindI("OrderList::Score::Essential", 200);
+ static int const ScoreImmediate = _config->FindI("OrderList::Score::Immediate", 10);
+ static int const ScorePreDepends = _config->FindI("OrderList::Score::PreDepends", 50);
+
int Score = 0;
if ((Pkg->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
- Score += 100;
+ Score += ScoreEssential;
if (IsFlag(Pkg,Immediate) == true)
- Score += 10;
-
- for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList();
+ Score += ScoreImmediate;
+
+ for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList();
D.end() == false; D++)
if (D->Type == pkgCache::Dep::PreDepends)
{
- Score += 50;
+ Score += ScorePreDepends;
break;
}
-
+
// Important Required Standard Optional Extra
signed short PrioMap[] = {0,5,4,3,1,0};
if (Cache[Pkg].InstVerIter(Cache)->Priority <= 5)
@@ -388,6 +405,7 @@ int pkgOrderList::OrderCompareA(const void *a, const void *b)
int ScoreA = Me->Score(A);
int ScoreB = Me->Score(B);
+
if (ScoreA > ScoreB)
return -1;
@@ -424,6 +442,7 @@ int pkgOrderList::OrderCompareB(const void *a, const void *b)
int ScoreA = Me->Score(A);
int ScoreB = Me->Score(B);
+
if (ScoreA > ScoreB)
return -1;
@@ -433,7 +452,6 @@ int pkgOrderList::OrderCompareB(const void *a, const void *b)
return strcmp(A.Name(),B.Name());
}
/*}}}*/
-
// OrderList::VisitDeps - Visit forward install dependencies /*{{{*/
// ---------------------------------------------------------------------
/* This calls the dependency function for the normal forwards dependencies
@@ -590,7 +608,6 @@ bool pkgOrderList::VisitNode(PkgIterator Pkg)
return true;
}
/*}}}*/
-
// OrderList::DepUnPackCrit - Critical UnPacking ordering /*{{{*/
// ---------------------------------------------------------------------
/* Critical unpacking ordering strives to satisfy Conflicts: and
@@ -668,13 +685,12 @@ bool pkgOrderList::DepUnPackCrit(DepIterator D)
}
return true;
}
-
+ /*}}}*/
// OrderList::DepUnPackPreD - Critical UnPacking ordering with depends /*{{{*/
// ---------------------------------------------------------------------
/* Critical PreDepends (also configure immediate and essential) strives to
ensure not only that all conflicts+predepends are met but that this
- package will be immediately configurable when it is unpacked.
-
+ package will be immediately configurable when it is unpacked.
Loops are preprocessed and logged. */
bool pkgOrderList::DepUnPackPreD(DepIterator D)
{
@@ -892,7 +908,6 @@ bool pkgOrderList::DepRemove(DepIterator D)
return true;
}
/*}}}*/
-
// OrderList::AddLoop - Add a loop to the loop list /*{{{*/
// ---------------------------------------------------------------------
/* We record the loops. This is a relic since loop breaking is done
diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc
index 304d1c653..491bff110 100644
--- a/apt-pkg/packagemanager.cc
+++ b/apt-pkg/packagemanager.cc
@@ -26,7 +26,7 @@
#include <apti18n.h>
#include <iostream>
#include <fcntl.h>
-
+ /*}}}*/
using namespace std;
// PM::PackageManager - Constructor /*{{{*/
@@ -57,7 +57,10 @@ bool pkgPackageManager::GetArchives(pkgAcquire *Owner,pkgSourceList *Sources,
if (CreateOrderList() == false)
return false;
- if (List->OrderUnpack() == false)
+ bool const ordering =
+ _config->FindB("PackageManager::UnpackAll",true) ?
+ List->OrderUnpack() : List->OrderCritical();
+ if (ordering == false)
return _error->Error("Internal ordering error");
for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++)
@@ -117,13 +120,12 @@ bool pkgPackageManager::FixMissing()
return Resolve.ResolveByKeep() == true && Cache.BrokenCount() == 0;
}
/*}}}*/
-
// PM::ImmediateAdd - Add the immediate flag recursivly /*{{{*/
// ---------------------------------------------------------------------
/* This adds the immediate flag to the pkg and recursively to the
dependendies
*/
-void pkgPackageManager::ImmediateAdd(PkgIterator I, bool UseInstallVer)
+void pkgPackageManager::ImmediateAdd(PkgIterator I, bool UseInstallVer, unsigned const int &Depth)
{
DepIterator D;
@@ -144,15 +146,14 @@ void pkgPackageManager::ImmediateAdd(PkgIterator I, bool UseInstallVer)
if(!List->IsFlag(D.TargetPkg(), pkgOrderList::Immediate))
{
if(Debug)
- clog << "ImmediateAdd(): Adding Immediate flag to " << I.Name() << endl;
+ clog << OutputInDepth(Depth) << "ImmediateAdd(): Adding Immediate flag to " << D.TargetPkg() << " cause of " << D.DepType() << " " << I.Name() << endl;
List->Flag(D.TargetPkg(),pkgOrderList::Immediate);
- ImmediateAdd(D.TargetPkg(), UseInstallVer);
+ ImmediateAdd(D.TargetPkg(), UseInstallVer, Depth + 1);
}
}
return;
}
/*}}}*/
-
// PM::CreateOrderList - Create the ordering class /*{{{*/
// ---------------------------------------------------------------------
/* This populates the ordering list with all the packages that are
@@ -165,7 +166,7 @@ bool pkgPackageManager::CreateOrderList()
delete List;
List = new pkgOrderList(&Cache);
- bool NoImmConfigure = !_config->FindB("APT::Immediate-Configure",true);
+ static bool const NoImmConfigure = !_config->FindB("APT::Immediate-Configure",true);
// Generate the list of affected packages and sort it
for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
@@ -268,13 +269,16 @@ bool pkgPackageManager::ConfigureAll()
if (OList.OrderConfigure() == false)
return false;
-
+
+ std::string const conf = _config->Find("PackageManager::Configure","all");
+ bool const ConfigurePkgs = (conf == "all");
+
// Perform the configuring
for (pkgOrderList::iterator I = OList.begin(); I != OList.end(); I++)
{
PkgIterator Pkg(Cache,*I);
- if (Configure(Pkg) == false)
+ if (ConfigurePkgs == true && Configure(Pkg) == false)
return false;
List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States);
@@ -289,20 +293,27 @@ bool pkgPackageManager::ConfigureAll()
of it's dependents. */
bool pkgPackageManager::SmartConfigure(PkgIterator Pkg)
{
+ if (Debug == true)
+ clog << "SmartConfigure " << Pkg.Name() << endl;
+
pkgOrderList OList(&Cache);
if (DepAdd(OList,Pkg) == false)
return false;
-
- if (OList.OrderConfigure() == false)
- return false;
-
+
+ static std::string const conf = _config->Find("PackageManager::Configure","all");
+ static bool const ConfigurePkgs = (conf == "all" || conf == "smart");
+
+ if (ConfigurePkgs == true)
+ if (OList.OrderConfigure() == false)
+ return false;
+
// Perform the configuring
for (pkgOrderList::iterator I = OList.begin(); I != OList.end(); I++)
{
PkgIterator Pkg(Cache,*I);
- if (Configure(Pkg) == false)
+ if (ConfigurePkgs == true && Configure(Pkg) == false)
return false;
List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States);
@@ -310,8 +321,9 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg)
// Sanity Check
if (List->IsFlag(Pkg,pkgOrderList::Configured) == false)
- return _error->Error("Internal error, could not immediate configure %s",Pkg.Name());
-
+ return _error->Error(_("Could not perform immediate configuration on '%s'."
+ "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.Name(),1);
+
return true;
}
/*}}}*/
@@ -463,7 +475,8 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg)
List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States);
if (List->IsFlag(Pkg,pkgOrderList::Immediate) == true)
if (SmartConfigure(Pkg) == false)
- return _error->Error("Internal Error, Could not perform immediate configuration (1) on %s",Pkg.Name());
+ return _error->Error(_("Could not perform immediate configuration on already unpacked '%s'."
+ "Please see man 5 apt.conf under APT::Immediate-Configure for details."),Pkg.Name());
return true;
}
@@ -479,6 +492,9 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg)
while (End->Type == pkgCache::Dep::PreDepends)
{
+ if (Debug == true)
+ clog << "PreDepends order for " << Pkg.Name() << std::endl;
+
// Look for possible ok targets.
SPtrArray<Version *> VList = Start.AllTargets();
bool Bad = true;
@@ -492,6 +508,8 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg)
Pkg.State() == PkgIterator::NeedsNothing)
{
Bad = false;
+ if (Debug == true)
+ clog << "Found ok package " << Pkg.Name() << endl;
continue;
}
}
@@ -507,6 +525,8 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg)
(Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing))
continue;
+ if (Debug == true)
+ clog << "Trying to SmartConfigure " << Pkg.Name() << endl;
Bad = !SmartConfigure(Pkg);
}
@@ -563,7 +583,8 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg)
// Perform immedate configuration of the package.
if (List->IsFlag(Pkg,pkgOrderList::Immediate) == true)
if (SmartConfigure(Pkg) == false)
- return _error->Error("Internal Error, Could not perform immediate configuration (2) on %s",Pkg.Name());
+ return _error->Error(_("Could not perform immediate configuration on '%s'."
+ "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.Name(),2);
return true;
}
@@ -579,9 +600,12 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall()
Reset();
if (Debug == true)
- clog << "Begining to order" << endl;
+ clog << "Beginning to order" << endl;
- if (List->OrderUnpack(FileNames) == false)
+ bool const ordering =
+ _config->FindB("PackageManager::UnpackAll",true) ?
+ List->OrderUnpack(FileNames) : List->OrderCritical();
+ if (ordering == false)
{
_error->Error("Internal ordering error");
return Failed;
@@ -634,7 +658,7 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall()
return Failed;
DoneSomething = true;
}
-
+
// Final run through the configure phase
if (ConfigureAll() == false)
return Failed;
diff --git a/apt-pkg/packagemanager.h b/apt-pkg/packagemanager.h
index a1bfdc52d..af1476b7a 100644
--- a/apt-pkg/packagemanager.h
+++ b/apt-pkg/packagemanager.h
@@ -49,7 +49,7 @@ class pkgPackageManager : protected pkgCache::Namespace
bool Debug;
bool DepAdd(pkgOrderList &Order,PkgIterator P,int Depth = 0);
- void ImmediateAdd(PkgIterator P, bool UseInstallVer);
+ void ImmediateAdd(PkgIterator P, bool UseInstallVer, unsigned const int &Depth = 0);
virtual OrderResult OrderInstall();
bool CheckRConflicts(PkgIterator Pkg,DepIterator Dep,const char *Ver);
bool CreateOrderList();
diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc
index 6687864ee..b0ce6e598 100644
--- a/apt-pkg/pkgcache.cc
+++ b/apt-pkg/pkgcache.cc
@@ -21,6 +21,7 @@
/*}}}*/
// Include Files /*{{{*/
#include <apt-pkg/pkgcache.h>
+#include <apt-pkg/policy.h>
#include <apt-pkg/indexfile.h>
#include <apt-pkg/version.h>
#include <apt-pkg/error.h>
@@ -49,7 +50,7 @@ pkgCache::Header::Header()
/* Whenever the structures change the major version should be bumped,
whenever the generator changes the minor version should be bumped. */
- MajorVersion = 7;
+ MajorVersion = 8;
MinorVersion = 0;
Dirty = false;
@@ -223,7 +224,7 @@ const char *pkgCache::DepType(unsigned char Type)
{
const char *Types[] = {"",_("Depends"),_("PreDepends"),_("Suggests"),
_("Recommends"),_("Conflicts"),_("Replaces"),
- _("Obsoletes"),_("Breaks")};
+ _("Obsoletes"),_("Breaks"), _("Enhances")};
if (Type < sizeof(Types)/sizeof(*Types))
return Types[Type];
return "";
@@ -274,13 +275,13 @@ pkgCache::PkgIterator::OkState pkgCache::PkgIterator::State() const
return NeedsUnpack;
if (Pkg->CurrentState == pkgCache::State::UnPacked ||
- Pkg->CurrentState == pkgCache::State::HalfConfigured ||
- //we don't need to care for triggers awaiting packages
- //dpkg will deal with them automatically when the
- //trigger pending action is run (those packages are usually
- //in half-configured or triggers-pending state)
+ Pkg->CurrentState == pkgCache::State::HalfConfigured)
+ // we leave triggers alone complettely. dpkg deals with
+ // them in a hard-to-predict manner and if they get
+ // resolved by dpkg before apt run dpkg --configure on
+ // the TriggersPending package dpkg returns a error
//Pkg->CurrentState == pkgCache::State::TriggersAwaited
- Pkg->CurrentState == pkgCache::State::TriggersPending)
+ //Pkg->CurrentState == pkgCache::State::TriggersPending)
return NeedsConfigure;
if (Pkg->CurrentState == pkgCache::State::HalfInstalled ||
@@ -290,6 +291,56 @@ pkgCache::PkgIterator::OkState pkgCache::PkgIterator::State() const
return NeedsNothing;
}
/*}}}*/
+// PkgIterator::CandVersion - Returns the candidate version string /*{{{*/
+// ---------------------------------------------------------------------
+/* Return string representing of the candidate version. */
+const char *
+pkgCache::PkgIterator::CandVersion() const
+{
+ //TargetVer is empty, so don't use it.
+ VerIterator version = pkgPolicy::pkgPolicy(Owner).GetCandidateVer(*this);
+ if (version.IsGood())
+ return version.VerStr();
+ return 0;
+};
+ /*}}}*/
+// PkgIterator::CurVersion - Returns the current version string /*{{{*/
+// ---------------------------------------------------------------------
+/* Return string representing of the current version. */
+const char *
+pkgCache::PkgIterator::CurVersion() const
+{
+ VerIterator version = CurrentVer();
+ if (version.IsGood())
+ return CurrentVer().VerStr();
+ return 0;
+};
+ /*}}}*/
+// ostream operator to handle string representation of a package /*{{{*/
+// ---------------------------------------------------------------------
+/* Output name < cur.rent.version -> candid.ate.version | new.est.version > (section)
+ Note that the characters <|>() are all literal above. Versions will be ommited
+ if they provide no new information (e.g. there is no newer version than candidate)
+ If no version and/or section can be found "none" is used. */
+std::ostream&
+operator<<(ostream& out, pkgCache::PkgIterator Pkg)
+{
+ if (Pkg.end() == true)
+ return out << "invalid package";
+
+ string current = string(Pkg.CurVersion() == 0 ? "none" : Pkg.CurVersion());
+ string candidate = string(Pkg.CandVersion() == 0 ? "none" : Pkg.CandVersion());
+ string newest = string(Pkg.VersionList().end() ? "none" : Pkg.VersionList().VerStr());
+
+ out << Pkg.Name() << " < " << current;
+ if (current != candidate)
+ out << " -> " << candidate;
+ if ( newest != "none" && candidate != newest)
+ out << " | " << newest;
+ out << " > ( " << string(Pkg.Section()==0?"none":Pkg.Section()) << " )";
+ return out;
+}
+ /*}}}*/
// DepIterator::IsCritical - Returns true if the dep is important /*{{{*/
// ---------------------------------------------------------------------
/* Currently critical deps are defined as depends, predepends and
@@ -607,6 +658,8 @@ string pkgCache::PkgFileIterator::RelStr()
Res = Res + (Res.empty() == true?"o=":",o=") + Origin();
if (Archive() != 0)
Res = Res + (Res.empty() == true?"a=":",a=") + Archive();
+ if (Codename() != 0)
+ Res = Res + (Res.empty() == true?"n=":",n=") + Codename();
if (Label() != 0)
Res = Res + (Res.empty() == true?"l=":",l=") + Label();
if (Component() != 0)
diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h
index 759e9a225..38733713f 100644
--- a/apt-pkg/pkgcache.h
+++ b/apt-pkg/pkgcache.h
@@ -27,7 +27,7 @@
using std::string;
class pkgVersioningSystem;
-class pkgCache
+class pkgCache /*{{{*/
{
public:
// Cache element predeclarations
@@ -70,7 +70,7 @@ class pkgCache
struct Dep
{
enum DepType {Depends=1,PreDepends=2,Suggests=3,Recommends=4,
- Conflicts=5,Replaces=6,Obsoletes=7,DpkgBreaks=8};
+ Conflicts=5,Replaces=6,Obsoletes=7,DpkgBreaks=8,Enhances=9};
enum DepCompareOp {Or=0x10,NoOp=0,LessEq=0x1,GreaterEq=0x2,Less=0x3,
Greater=0x4,Equals=0x5,NotEquals=0x6};
};
@@ -146,8 +146,8 @@ class pkgCache
pkgCache(MMap *Map,bool DoMap = true);
virtual ~pkgCache() {};
};
-
-// Header structure
+ /*}}}*/
+// Header structure /*{{{*/
struct pkgCache::Header
{
// Signature information
@@ -195,8 +195,8 @@ struct pkgCache::Header
bool CheckSizes(Header &Against) const;
Header();
};
-
-struct pkgCache::Package
+ /*}}}*/
+struct pkgCache::Package /*{{{*/
{
// Pointers
map_ptrloc Name; // Stringtable
@@ -217,12 +217,13 @@ struct pkgCache::Package
unsigned int ID;
unsigned long Flags;
};
-
-struct pkgCache::PackageFile
+ /*}}}*/
+struct pkgCache::PackageFile /*{{{*/
{
// Names
map_ptrloc FileName; // Stringtable
map_ptrloc Archive; // Stringtable
+ map_ptrloc Codename; // Stringtable
map_ptrloc Component; // Stringtable
map_ptrloc Version; // Stringtable
map_ptrloc Origin; // Stringtable
@@ -238,24 +239,24 @@ struct pkgCache::PackageFile
unsigned int ID;
time_t mtime; // Modification time for the file
};
-
-struct pkgCache::VerFile
+ /*}}}*/
+struct pkgCache::VerFile /*{{{*/
{
map_ptrloc File; // PackageFile
map_ptrloc NextFile; // PkgVerFile
map_ptrloc Offset; // File offset
unsigned short Size;
};
-
-struct pkgCache::DescFile
+ /*}}}*/
+struct pkgCache::DescFile /*{{{*/
{
map_ptrloc File; // PackageFile
map_ptrloc NextFile; // PkgVerFile
map_ptrloc Offset; // File offset
unsigned short Size;
};
-
-struct pkgCache::Version
+ /*}}}*/
+struct pkgCache::Version /*{{{*/
{
map_ptrloc VerStr; // Stringtable
map_ptrloc Section; // StringTable (StringItem)
@@ -275,8 +276,8 @@ struct pkgCache::Version
unsigned int ID;
unsigned char Priority;
};
-
-struct pkgCache::Description
+ /*}}}*/
+struct pkgCache::Description /*{{{*/
{
// Language Code store the description translation language code. If
// the value has a 0 lenght then this is readed using the Package
@@ -291,8 +292,8 @@ struct pkgCache::Description
unsigned int ID;
};
-
-struct pkgCache::Dependency
+ /*}}}*/
+struct pkgCache::Dependency /*{{{*/
{
map_ptrloc Version; // Stringtable
map_ptrloc Package; // Package
@@ -305,8 +306,8 @@ struct pkgCache::Dependency
unsigned char Type;
unsigned char CompareOp;
};
-
-struct pkgCache::Provides
+ /*}}}*/
+struct pkgCache::Provides /*{{{*/
{
map_ptrloc ParentPkg; // Pacakge
map_ptrloc Version; // Version
@@ -314,13 +315,13 @@ struct pkgCache::Provides
map_ptrloc NextProvides; // Provides
map_ptrloc NextPkgProv; // Provides
};
-
-struct pkgCache::StringItem
+ /*}}}*/
+struct pkgCache::StringItem /*{{{*/
{
map_ptrloc String; // Stringtable
map_ptrloc NextItem; // StringItem
};
-
+ /*}}}*/
#include <apt-pkg/cacheiterators.h>
inline pkgCache::PkgIterator pkgCache::PkgBegin()
@@ -333,7 +334,7 @@ inline pkgCache::PkgFileIterator pkgCache::FileEnd()
{return PkgFileIterator(*this,PkgFileP);};
// Oh I wish for Real Name Space Support
-class pkgCache::Namespace
+class pkgCache::Namespace /*{{{*/
{
public:
@@ -351,5 +352,5 @@ class pkgCache::Namespace
typedef pkgCache::Dep Dep;
typedef pkgCache::Flag Flag;
};
-
+ /*}}}*/
#endif
diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc
index 397c19829..68180c702 100644
--- a/apt-pkg/pkgcachegen.cc
+++ b/apt-pkg/pkgcachegen.cc
@@ -53,14 +53,16 @@ pkgCacheGenerator::pkgCacheGenerator(DynamicMMap *pMap,OpProgress *Prog) :
{
// Setup the map interface..
Cache.HeaderP = (pkgCache::Header *)Map.Data();
- Map.RawAllocate(sizeof(pkgCache::Header));
+ if (Map.RawAllocate(sizeof(pkgCache::Header)) == 0 && _error->PendingError() == true)
+ return;
+
Map.UsePools(*Cache.HeaderP->Pools,sizeof(Cache.HeaderP->Pools)/sizeof(Cache.HeaderP->Pools[0]));
-
+
// Starting header
*Cache.HeaderP = pkgCache::Header();
Cache.HeaderP->VerSysName = Map.WriteString(_system->VS->Label);
Cache.HeaderP->Architecture = Map.WriteString(_config->Find("APT::Architecture"));
- Cache.ReMap();
+ Cache.ReMap();
}
else
{
@@ -135,7 +137,7 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
pkgCache::VerIterator Ver = Pkg.VersionList();
map_ptrloc *LastVer = &Pkg->VersionList;
- for (; Ver.end() == false; LastVer = &Ver->NextVer, Ver++)
+ for (; Ver.end() == false; LastVer = &Ver->NextVer, Ver++)
{
pkgCache::DescIterator Desc = Ver.DescriptionList();
map_ptrloc *LastDesc = &Ver->DescriptionList;
@@ -143,7 +145,7 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
// don't add a new description if we have one for the given
// md5 && language
- for ( ; Desc.end() == false; Desc++)
+ for ( ; Desc.end() == false; Desc++)
if (MD5SumValue(Desc.md5()) == CurMd5 &&
Desc.LanguageCode() == List.DescriptionLanguage())
duplicate=true;
@@ -151,7 +153,7 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
continue;
for (Desc = Ver.DescriptionList();
- Desc.end() == false;
+ Desc.end() == false;
LastDesc = &Desc->NextDesc, Desc++)
{
if (MD5SumValue(Desc.md5()) == CurMd5)
@@ -160,7 +162,7 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
*LastDesc = NewDescription(Desc, List.DescriptionLanguage(), CurMd5, *LastDesc);
Desc->ParentPkg = Pkg.Index();
- if (NewFileDesc(Desc,List) == false)
+ if ((*LastDesc == 0 && _error->PendingError()) || NewFileDesc(Desc,List) == false)
return _error->Error(_("Error occurred while processing %s (NewFileDesc1)"),PackageName.c_str());
break;
}
@@ -220,7 +222,7 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
Ver->ParentPkg = Pkg.Index();
Ver->Hash = Hash;
- if (List.NewVersion(Ver) == false)
+ if ((*LastVer == 0 && _error->PendingError()) || List.NewVersion(Ver) == false)
return _error->Error(_("Error occurred while processing %s (NewVersion1)"),
PackageName.c_str());
@@ -252,7 +254,7 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
*LastDesc = NewDescription(Desc, List.DescriptionLanguage(), List.Description_md5(), *LastDesc);
Desc->ParentPkg = Pkg.Index();
- if (NewFileDesc(Desc,List) == false)
+ if ((*LastDesc == 0 && _error->PendingError()) || NewFileDesc(Desc,List) == false)
return _error->Error(_("Error occurred while processing %s (NewFileDesc2)"),PackageName.c_str());
}
@@ -419,7 +421,7 @@ bool pkgCacheGenerator::NewFileDesc(pkgCache::DescIterator &Desc,
// Get a structure
unsigned long DescFile = Map.Allocate(sizeof(pkgCache::DescFile));
if (DescFile == 0)
- return 0;
+ return false;
pkgCache::DescFileIterator DF(Cache,Cache.DescFileP + DescFile);
DF->File = CurrentFile - Cache.PkgFileP;
@@ -460,6 +462,8 @@ map_ptrloc pkgCacheGenerator::NewDescription(pkgCache::DescIterator &Desc,
Desc->ID = Cache.HeaderP->DescriptionCount++;
Desc->language_code = Map.WriteString(Lang);
Desc->md5sum = Map.WriteString(md5sum.Value());
+ if (Desc->language_code == 0 || Desc->md5sum == 0)
+ return 0;
return Description;
}
@@ -652,7 +656,6 @@ unsigned long pkgCacheGenerator::WriteUniqString(const char *S,
return ItemP->String;
}
/*}}}*/
-
// CheckValidity - Check that a cache is up-to-date /*{{{*/
// ---------------------------------------------------------------------
/* This just verifies that each file in the list of index files exists,
@@ -667,7 +670,7 @@ static bool CheckValidity(const string &CacheFile, FileIterator Start,
// Map it
FileFd CacheF(CacheFile,FileFd::ReadOnly);
- SPtr<MMap> Map = new MMap(CacheF,MMap::Public | MMap::ReadOnly);
+ SPtr<MMap> Map = new MMap(CacheF,0);
pkgCache Cache(Map);
if (_error->PendingError() == true || Map->Size() == 0)
{
@@ -810,7 +813,7 @@ bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress,
unsigned long EndOfSource = Files.size();
if (_system->AddStatusFiles(Files) == false)
return false;
-
+
// Decide if we can write to the files..
string CacheFile = _config->FindFile("Dir::Cache::pkgcache");
string SrcCacheFile = _config->FindFile("Dir::Cache::srcpkgcache");
@@ -851,7 +854,7 @@ bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress,
else
{
// Just build it in memory..
- Map = new DynamicMMap(MMap::Public,MapSize);
+ Map = new DynamicMMap(0,MapSize);
}
// Lets try the source cache.
@@ -862,8 +865,10 @@ bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress,
{
// Preload the map with the source cache
FileFd SCacheF(SrcCacheFile,FileFd::ReadOnly);
- if (SCacheF.Read((unsigned char *)Map->Data() + Map->RawAllocate(SCacheF.Size()),
- SCacheF.Size()) == false)
+ unsigned long alloc = Map->RawAllocate(SCacheF.Size());
+ if ((alloc == 0 && _error->PendingError())
+ || SCacheF.Read((unsigned char *)Map->Data() + alloc,
+ SCacheF.Size()) == false)
return false;
TotalSize = ComputeSize(Files.begin()+EndOfSource,Files.end());
@@ -924,7 +929,7 @@ bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress,
if (CacheF != 0)
{
delete Map.UnGuard();
- *OutMap = new MMap(*CacheF,MMap::Public | MMap::ReadOnly);
+ *OutMap = new MMap(*CacheF,0);
}
else
{
@@ -946,8 +951,7 @@ bool pkgMakeOnlyStatusCache(OpProgress &Progress,DynamicMMap **OutMap)
if (_system->AddStatusFiles(Files) == false)
return false;
- SPtr<DynamicMMap> Map;
- Map = new DynamicMMap(MMap::Public,MapSize);
+ SPtr<DynamicMMap> Map = new DynamicMMap(0,MapSize);
unsigned long CurrentSize = 0;
unsigned long TotalSize = 0;
diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h
index b6715294a..108b34207 100644
--- a/apt-pkg/pkgcachegen.h
+++ b/apt-pkg/pkgcachegen.h
@@ -28,7 +28,7 @@ class OpProgress;
class MMap;
class pkgIndexFile;
-class pkgCacheGenerator
+class pkgCacheGenerator /*{{{*/
{
private:
@@ -76,8 +76,8 @@ class pkgCacheGenerator
pkgCacheGenerator(DynamicMMap *Map,OpProgress *Progress);
~pkgCacheGenerator();
};
-
-// This is the abstract package list parser class.
+ /*}}}*/
+// This is the abstract package list parser class. /*{{{*/
class pkgCacheGenerator::ListParser
{
pkgCacheGenerator *Owner;
@@ -126,7 +126,7 @@ class pkgCacheGenerator::ListParser
ListParser() : FoundFileDeps(false) {};
virtual ~ListParser() {};
};
-
+ /*}}}*/
bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress,
MMap **OutMap = 0,bool AllowMem = false);
bool pkgMakeOnlyStatusCache(OpProgress &Progress,DynamicMMap **OutMap);
diff --git a/apt-pkg/pkgrecords.h b/apt-pkg/pkgrecords.h
index 17f3b1569..c2c98188a 100644
--- a/apt-pkg/pkgrecords.h
+++ b/apt-pkg/pkgrecords.h
@@ -22,7 +22,7 @@
#include <apt-pkg/fileutl.h>
#include <vector>
-class pkgRecords
+class pkgRecords /*{{{*/
{
public:
class Parser;
@@ -42,8 +42,8 @@ class pkgRecords
pkgRecords(pkgCache &Cache);
~pkgRecords();
};
-
-class pkgRecords::Parser
+ /*}}}*/
+class pkgRecords::Parser /*{{{*/
{
protected:
@@ -73,5 +73,5 @@ class pkgRecords::Parser
virtual ~Parser() {};
};
-
+ /*}}}*/
#endif
diff --git a/apt-pkg/policy.cc b/apt-pkg/policy.cc
index 8b083fd44..81fdb0431 100644
--- a/apt-pkg/policy.cc
+++ b/apt-pkg/policy.cc
@@ -32,6 +32,9 @@
#include <apti18n.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <algorithm>
#include <iostream>
#include <sstream>
/*}}}*/
@@ -120,6 +123,14 @@ pkgCache::VerIterator pkgPolicy::GetCandidateVer(pkgCache::PkgIterator Pkg)
signed Max = GetPriority(Pkg);
pkgCache::VerIterator Pref = GetMatch(Pkg);
+ // no package = no candidate version
+ if (Pkg.end() == true)
+ return Pref;
+
+ // packages with a pin lower than 0 have no newer candidate than the current version
+ if (Max < 0)
+ return Pkg.CurrentVer();
+
/* Falling through to the default version.. Setting Max to zero
effectively excludes everything <= 0 which are the non-automatic
priorities.. The status file is given a prio of 100 which will exclude
@@ -239,7 +250,76 @@ signed short pkgPolicy::GetPriority(pkgCache::PkgIterator const &Pkg)
return 0;
}
/*}}}*/
+// PreferenceSection class - Overriding the default TrimRecord method /*{{{*/
+// ---------------------------------------------------------------------
+/* The preference file is a user generated file so the parser should
+ therefore be a bit more friendly by allowing comments and new lines
+ all over the place rather than forcing a special format */
+class PreferenceSection : public pkgTagSection
+{
+ void TrimRecord(bool BeforeRecord, const char* &End)
+ {
+ for (; Stop < End && (Stop[0] == '\n' || Stop[0] == '\r' || Stop[0] == '#'); Stop++)
+ if (Stop[0] == '#')
+ Stop = (const char*) memchr(Stop,'\n',End-Stop);
+ }
+};
+ /*}}}*/
+// ReadPinDir - Load the pin files from this dir into a Policy /*{{{*/
+// ---------------------------------------------------------------------
+/* This will load each pin file in the given dir into a Policy. If the
+ given dir is empty the dir set in Dir::Etc::PreferencesParts is used.
+ Note also that this method will issue a warning if the dir does not
+ exists but it will return true in this case! */
+bool ReadPinDir(pkgPolicy &Plcy,string Dir)
+{
+ if (Dir.empty() == true)
+ Dir = _config->FindDir("Dir::Etc::PreferencesParts");
+
+ if (FileExists(Dir) == false)
+ {
+ _error->WarningE("FileExists",_("Unable to read %s"),Dir.c_str());
+ return true;
+ }
+
+ DIR *D = opendir(Dir.c_str());
+ if (D == 0)
+ return _error->Errno("opendir",_("Unable to read %s"),Dir.c_str());
+
+ vector<string> List;
+ for (struct dirent *Ent = readdir(D); Ent != 0; Ent = readdir(D))
+ {
+ if (Ent->d_name[0] == '.')
+ continue;
+
+ // Skip bad file names ala run-parts
+ const char *C = Ent->d_name;
+ for (; *C != 0; C++)
+ if (isalpha(*C) == 0 && isdigit(*C) == 0 && *C != '_' && *C != '-')
+ break;
+ if (*C != 0)
+ continue;
+
+ // Make sure it is a file and not something else
+ string File = flCombine(Dir,Ent->d_name);
+ struct stat St;
+ if (stat(File.c_str(),&St) != 0 || S_ISREG(St.st_mode) == 0)
+ continue;
+
+ List.push_back(File);
+ }
+ closedir(D);
+
+ sort(List.begin(),List.end());
+
+ // Read the files
+ for (vector<string>::const_iterator I = List.begin(); I != List.end(); I++)
+ if (ReadPinFile(Plcy, *I) == false)
+ return false;
+ return true;
+}
+ /*}}}*/
// ReadPinFile - Load the pin file into a Policy /*{{{*/
// ---------------------------------------------------------------------
/* I'd like to see the preferences file store more than just pin information
@@ -259,12 +339,12 @@ bool ReadPinFile(pkgPolicy &Plcy,string File)
if (_error->PendingError() == true)
return false;
- pkgTagSection Tags;
+ PreferenceSection Tags;
while (TF.Step(Tags) == true)
{
string Name = Tags.FindS("Package");
if (Name.empty() == true)
- return _error->Error(_("Invalid record in the preferences file, no Package header"));
+ return _error->Error(_("Invalid record in the preferences file %s, no Package header"), File.c_str());
if (Name == "*")
Name = string();
diff --git a/apt-pkg/policy.h b/apt-pkg/policy.h
index d5f3b2f75..4894682fa 100644
--- a/apt-pkg/policy.h
+++ b/apt-pkg/policy.h
@@ -84,5 +84,6 @@ class pkgPolicy : public pkgDepCache::Policy
};
bool ReadPinFile(pkgPolicy &Plcy,string File = "");
+bool ReadPinDir(pkgPolicy &Plcy,string Dir = "");
#endif
diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc
index fea645078..4b3abe918 100644
--- a/apt-pkg/sourcelist.cc
+++ b/apt-pkg/sourcelist.cc
@@ -157,13 +157,20 @@ bool pkgSourceList::ReadMainList()
// CNC:2003-11-28 - Entries in sources.list have priority over
// entries in sources.list.d.
string Main = _config->FindFile("Dir::Etc::sourcelist");
+ string Parts = _config->FindDir("Dir::Etc::sourceparts");
+
if (FileExists(Main) == true)
- Res &= ReadAppend(Main);
+ Res &= ReadAppend(Main);
+ else if (FileExists(Parts) == false)
+ // Only warn if there are no sources.list.d.
+ _error->WarningE("FileExists",_("Unable to read %s"),Main.c_str());
- string Parts = _config->FindDir("Dir::Etc::sourceparts");
if (FileExists(Parts) == true)
Res &= ReadSourceDir(Parts);
-
+ else if (FileExists(Main) == false)
+ // Only warn if there is no sources.list file.
+ _error->WarningE("FileExists",_("Unable to read %s"),Parts.c_str());
+
return Res;
}
/*}}}*/
diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc
index 893cb8ee7..7c5d15a58 100644
--- a/apt-pkg/tagfile.cc
+++ b/apt-pkg/tagfile.cc
@@ -81,7 +81,7 @@ bool pkgTagFile::Resize()
End = Start + EndSize;
return true;
}
-
+ /*}}}*/
// TagFile::Step - Advance to the next section /*{{{*/
// ---------------------------------------------------------------------
/* If the Section Scanner fails we refill the buffer and try again.
@@ -212,10 +212,12 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength)
if (Stop == 0)
return false;
-
+
TagCount = 0;
while (TagCount+1 < sizeof(Indexes)/sizeof(Indexes[0]) && Stop < End)
{
+ TrimRecord(true,End);
+
// Start a new index and add it to the hash
if (isspace(Stop[0]) == 0)
{
@@ -227,14 +229,14 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength)
if (Stop == 0)
return false;
-
+
for (; Stop+1 < End && Stop[1] == '\r'; Stop++);
// Double newline marks the end of the record
if (Stop+1 < End && Stop[1] == '\n')
{
Indexes[TagCount] = Stop - Section;
- for (; Stop < End && (Stop[0] == '\n' || Stop[0] == '\r'); Stop++);
+ TrimRecord(false,End);
return true;
}
@@ -244,6 +246,16 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength)
return false;
}
/*}}}*/
+// TagSection::TrimRecord - Trim off any garbage before/after a record /*{{{*/
+// ---------------------------------------------------------------------
+/* There should be exactly 2 newline at the end of the record, no more. */
+void pkgTagSection::TrimRecord(bool BeforeRecord, const char*& End)
+{
+ if (BeforeRecord == true)
+ return;
+ for (; Stop < End && (Stop[0] == '\n' || Stop[0] == '\r'); Stop++);
+}
+ /*}}}*/
// TagSection::Trim - Trim off any trailing garbage /*{{{*/
// ---------------------------------------------------------------------
/* There should be exactly 1 newline at the end of the buffer, no more. */
@@ -390,7 +402,6 @@ bool pkgTagSection::FindFlag(const char *Tag,unsigned long &Flags,
return true;
}
/*}}}*/
-
// TFRewrite - Rewrite a control record /*{{{*/
// ---------------------------------------------------------------------
/* This writes the control record to stdout rewriting it as necessary. The
diff --git a/apt-pkg/tagfile.h b/apt-pkg/tagfile.h
index 6536932dd..321329a23 100644
--- a/apt-pkg/tagfile.h
+++ b/apt-pkg/tagfile.h
@@ -27,7 +27,6 @@
class pkgTagSection
{
const char *Section;
- const char *Stop;
// We have a limit of 256 tags per section.
unsigned int Indexes[256];
@@ -35,6 +34,9 @@ class pkgTagSection
unsigned int TagCount;
+ protected:
+ const char *Stop;
+
public:
inline bool operator ==(const pkgTagSection &rhs) {return Section == rhs.Section;};
@@ -49,6 +51,7 @@ class pkgTagSection
bool Scan(const char *Start,unsigned long MaxLength);
inline unsigned long size() const {return Stop - Section;};
void Trim();
+ virtual void TrimRecord(bool BeforeRecord, const char* &End);
inline unsigned int Count() const {return TagCount;};
inline void Get(const char *&Start,const char *&Stop,unsigned int I) const
diff --git a/apt-pkg/vendorlist.cc b/apt-pkg/vendorlist.cc
index 8e5d09e8a..589997081 100644
--- a/apt-pkg/vendorlist.cc
+++ b/apt-pkg/vendorlist.cc
@@ -10,7 +10,7 @@ pkgVendorList::~pkgVendorList()
delete *I;
}
-// pkgVendorList::ReadMainList - Read list of known package vendors /*{{{*/
+// pkgVendorList::ReadMainList - Read list of known package vendors /*{{{*/
// ---------------------------------------------------------------------
/* This also scans a directory of vendor files similar to apt.conf.d
which can contain the usual suspects of distribution provided data.
@@ -31,8 +31,8 @@ bool pkgVendorList::ReadMainList()
return CreateList(Cnf);
}
-
-bool pkgVendorList::Read(string File)
+ /*}}}*/
+bool pkgVendorList::Read(string File) /*{{{*/
{
Configuration Cnf;
if (ReadConfigFile(Cnf,File,true) == false)
@@ -40,8 +40,8 @@ bool pkgVendorList::Read(string File)
return CreateList(Cnf);
}
-
-bool pkgVendorList::CreateList(Configuration& Cnf)
+ /*}}}*/
+bool pkgVendorList::CreateList(Configuration& Cnf) /*{{{*/
{
for (vector<const Vendor *>::const_iterator I = VendorList.begin();
I != VendorList.end(); I++)
@@ -110,8 +110,8 @@ bool pkgVendorList::CreateList(Configuration& Cnf)
return !_error->PendingError();
}
-
-const Vendor* pkgVendorList::LookupFingerprint(string Fingerprint)
+ /*}}}*/
+const Vendor* pkgVendorList::LookupFingerprint(string Fingerprint) /*{{{*/
{
for (const_iterator I = VendorList.begin(); I != VendorList.end(); ++I)
{
@@ -121,8 +121,8 @@ const Vendor* pkgVendorList::LookupFingerprint(string Fingerprint)
return NULL;
}
-
-const Vendor* pkgVendorList::FindVendor(const std::vector<string> GPGVOutput)
+ /*}}}*/
+const Vendor* pkgVendorList::FindVendor(const std::vector<string> GPGVOutput) /*{{{*/
{
for (std::vector<string>::const_iterator I = GPGVOutput.begin(); I != GPGVOutput.end(); I++)
{
@@ -142,3 +142,4 @@ const Vendor* pkgVendorList::FindVendor(const std::vector<string> GPGVOutput)
return NULL;
}
+ /*}}}*/
diff --git a/apt-pkg/versionmatch.cc b/apt-pkg/versionmatch.cc
index 5c25c2f7b..b4d1d4696 100644
--- a/apt-pkg/versionmatch.cc
+++ b/apt-pkg/versionmatch.cc
@@ -63,8 +63,8 @@ pkgVersionMatch::pkgVersionMatch(string Data,MatchType Type) : Type(Type)
if (isdigit(Data[0]))
RelVerStr = Data;
else
- RelArchive = Data;
-
+ RelRelease = Data;
+
if (RelVerStr.length() > 0 && RelVerStr.end()[-1] == '*')
{
RelVerPrefixMatch = true;
@@ -87,19 +87,21 @@ pkgVersionMatch::pkgVersionMatch(string Data,MatchType Type) : Type(Type)
{
if (strlen(Fragments[J]) < 3)
continue;
-
+
if (stringcasecmp(Fragments[J],Fragments[J]+2,"v=") == 0)
RelVerStr = Fragments[J]+2;
else if (stringcasecmp(Fragments[J],Fragments[J]+2,"o=") == 0)
RelOrigin = Fragments[J]+2;
else if (stringcasecmp(Fragments[J],Fragments[J]+2,"a=") == 0)
RelArchive = Fragments[J]+2;
+ else if (stringcasecmp(Fragments[J],Fragments[J]+2,"n=") == 0)
+ RelCodename = Fragments[J]+2;
else if (stringcasecmp(Fragments[J],Fragments[J]+2,"l=") == 0)
RelLabel = Fragments[J]+2;
else if (stringcasecmp(Fragments[J],Fragments[J]+2,"c=") == 0)
RelComponent = Fragments[J]+2;
}
-
+
if (RelVerStr.end()[-1] == '*')
{
RelVerPrefixMatch = true;
@@ -169,15 +171,16 @@ bool pkgVersionMatch::FileMatch(pkgCache::PkgFileIterator File)
{
if (MatchAll == true)
return true;
-
+
/* cout << RelVerStr << ',' << RelOrigin << ',' << RelArchive << ',' << RelLabel << endl;
cout << File.Version() << ',' << File.Origin() << ',' << File.Archive() << ',' << File.Label() << endl;*/
-
+
if (RelVerStr.empty() == true && RelOrigin.empty() == true &&
RelArchive.empty() == true && RelLabel.empty() == true &&
+ RelRelease.empty() == true && RelCodename.empty() == true &&
RelComponent.empty() == true)
return false;
-
+
if (RelVerStr.empty() == false)
if (File->Version == 0 ||
MatchVer(File.Version(),RelVerStr,RelVerPrefixMatch) == false)
@@ -187,11 +190,19 @@ bool pkgVersionMatch::FileMatch(pkgCache::PkgFileIterator File)
stringcasecmp(RelOrigin,File.Origin()) != 0)
return false;
if (RelArchive.empty() == false)
- {
- if (File->Archive == 0 ||
+ if (File->Archive == 0 ||
stringcasecmp(RelArchive,File.Archive()) != 0)
- return false;
- }
+ return false;
+ if (RelCodename.empty() == false)
+ if (File->Codename == 0 ||
+ stringcasecmp(RelCodename,File.Codename()) != 0)
+ return false;
+ if (RelRelease.empty() == false)
+ if ((File->Archive == 0 ||
+ stringcasecmp(RelRelease,File.Archive()) != 0) &&
+ (File->Codename == 0 ||
+ stringcasecmp(RelRelease,File.Codename()) != 0))
+ return false;
if (RelLabel.empty() == false)
if (File->Label == 0 ||
stringcasecmp(RelLabel,File.Label()) != 0)
@@ -202,7 +213,7 @@ bool pkgVersionMatch::FileMatch(pkgCache::PkgFileIterator File)
return false;
return true;
}
-
+
if (Type == Origin)
{
if (OrSite.empty() == false) {
@@ -213,7 +224,7 @@ bool pkgVersionMatch::FileMatch(pkgCache::PkgFileIterator File)
return false;
return (OrSite == File.Site()); /* both strings match */
}
-
+
return false;
}
/*}}}*/
diff --git a/apt-pkg/versionmatch.h b/apt-pkg/versionmatch.h
index fe264aa46..a8f3c84ac 100644
--- a/apt-pkg/versionmatch.h
+++ b/apt-pkg/versionmatch.h
@@ -3,29 +3,32 @@
// $Id: versionmatch.h,v 1.4 2001/05/29 03:07:12 jgg Exp $
/* ######################################################################
- Version Matching
-
+ Version Matching
+
This module takes a matching string and a type and locates the version
record that satisfies the constraint described by the matching string.
Version: 1.2*
Release: o=Debian,v=2.1*,c=main
Release: v=2.1*
+ Release: a=testing
+ Release: n=squeeze
Release: *
Origin: ftp.debian.org
-
+
Release may be a complex type that can specify matches for any of:
Version (v= with prefix)
Origin (o=)
- Archive (a=)
+ Archive (a=) eg, unstable, testing, stable
+ Codename (n=) e.g. etch, lenny, squeeze, sid
Label (l=)
Component (c=)
If there are no equals signs in the string then it is scanned in short
- form - if it starts with a number it is Version otherwise it is an
- Archive.
-
+ form - if it starts with a number it is Version otherwise it is an
+ Archive or a Codename.
+
Release may be a '*' to match all releases.
-
+
##################################################################### */
/*}}}*/
#ifndef PKGLIB_VERSIONMATCH_H
@@ -47,6 +50,8 @@ class pkgVersionMatch
string RelVerStr;
bool RelVerPrefixMatch;
string RelOrigin;
+ string RelRelease;
+ string RelCodename;
string RelArchive;
string RelLabel;
string RelComponent;