summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/acquire-item.cc48
-rw-r--r--apt-pkg/acquire-item.h2
-rw-r--r--apt-pkg/algorithms.cc51
-rw-r--r--apt-pkg/algorithms.h4
-rw-r--r--apt-pkg/aptconfiguration.cc4
-rw-r--r--apt-pkg/cachefilter.cc11
-rw-r--r--apt-pkg/cachefilter.h84
-rw-r--r--apt-pkg/cacheset.cc64
-rw-r--r--apt-pkg/cacheset.h14
-rw-r--r--apt-pkg/cdrom.h2
-rw-r--r--apt-pkg/contrib/cdromutl.cc3
-rw-r--r--apt-pkg/contrib/cmndline.cc49
-rw-r--r--apt-pkg/contrib/cmndline.h6
-rw-r--r--apt-pkg/contrib/configuration.cc14
-rw-r--r--apt-pkg/contrib/configuration.h1
-rw-r--r--apt-pkg/contrib/error.cc10
-rw-r--r--apt-pkg/contrib/fileutl.cc94
-rw-r--r--apt-pkg/contrib/fileutl.h3
-rw-r--r--apt-pkg/contrib/sha2.h4
-rw-r--r--apt-pkg/contrib/strutl.cc20
-rw-r--r--apt-pkg/contrib/strutl.h4
-rw-r--r--apt-pkg/deb/deblistparser.cc104
-rw-r--r--apt-pkg/deb/debmetaindex.cc1
-rw-r--r--apt-pkg/deb/dpkgpm.cc60
-rw-r--r--apt-pkg/depcache.cc6
-rw-r--r--apt-pkg/indexcopy.cc5
-rw-r--r--apt-pkg/indexrecords.cc17
-rw-r--r--apt-pkg/policy.cc25
-rw-r--r--apt-pkg/tagfile.cc69
-rw-r--r--apt-pkg/tagfile.h3
-rw-r--r--apt-pkg/vendorlist.cc2
31 files changed, 587 insertions, 197 deletions
diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc
index c48443eff..97b2d1e29 100644
--- a/apt-pkg/acquire-item.cc
+++ b/apt-pkg/acquire-item.cc
@@ -984,6 +984,8 @@ void pkgAcqIndex::Done(string Message,unsigned long long Size,string Hash,
DestFile += ".decomp";
Desc.URI = decompProg + ":" + FileName;
QueueURI(Desc);
+
+ // FIXME: this points to a c++ string that goes out of scope
Mode = decompProg.c_str();
}
/*}}}*/
@@ -1067,8 +1069,7 @@ pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire *Owner, /*{{{*/
string Final = _config->FindDir("Dir::State::lists");
Final += URItoFileName(RealURI);
- struct stat Buf;
- if (stat(Final.c_str(),&Buf) == 0)
+ if (RealFileExists(Final) == true)
{
// File was already in place. It needs to be re-downloaded/verified
// because Release might have changed, we do give it a differnt
@@ -1082,6 +1083,19 @@ pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire *Owner, /*{{{*/
QueueURI(Desc);
}
/*}}}*/
+pkgAcqMetaSig::~pkgAcqMetaSig() /*{{{*/
+{
+ // if the file was never queued undo file-changes done in the constructor
+ if (QueueCounter == 1 && Status == StatIdle && FileSize == 0 && Complete == false &&
+ LastGoodSig.empty() == false)
+ {
+ string const Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
+ if (RealFileExists(Final) == false && RealFileExists(LastGoodSig) == true)
+ Rename(LastGoodSig, Final);
+ }
+
+}
+ /*}}}*/
// pkgAcqMetaSig::Custom600Headers - Insert custom request headers /*{{{*/
// ---------------------------------------------------------------------
/* The only header we use is the last-modified header. */
@@ -1369,9 +1383,20 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify) /*{{{*/
{
HashString ExpectedIndexHash;
const indexRecords::checkSum *Record = MetaIndexParser->Lookup((*Target)->MetaKey);
+ bool compressedAvailable = false;
if (Record == NULL)
{
- if (verify == true && (*Target)->IsOptional() == false)
+ if ((*Target)->IsOptional() == true)
+ {
+ std::vector<std::string> types = APT::Configuration::getCompressionTypes();
+ for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
+ if (MetaIndexParser->Exists(string((*Target)->MetaKey).append(".").append(*t)) == true)
+ {
+ compressedAvailable = true;
+ break;
+ }
+ }
+ else if (verify == true)
{
Status = StatAuthError;
strprintf(ErrorText, _("Unable to find expected entry '%s' in Release file (Wrong sources.list entry or malformed file)"), (*Target)->MetaKey.c_str());
@@ -1400,7 +1425,7 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify) /*{{{*/
if ((*Target)->IsSubIndex() == true)
new pkgAcqSubIndex(Owner, (*Target)->URI, (*Target)->Description,
(*Target)->ShortDesc, ExpectedIndexHash);
- else if (transInRelease == false || MetaIndexParser->Exists((*Target)->MetaKey) == true)
+ else if (transInRelease == false || Record != NULL || compressedAvailable == true)
{
if (_config->FindB("Acquire::PDiffs",true) == true && transInRelease == true &&
MetaIndexParser->Exists(string((*Target)->MetaKey).append(".diff/Index")) == true)
@@ -1584,14 +1609,25 @@ pkgAcqMetaClearSig::pkgAcqMetaClearSig(pkgAcquire *Owner, /*{{{*/
// keep the old InRelease around in case of transistent network errors
string const Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
- struct stat Buf;
- if (stat(Final.c_str(),&Buf) == 0)
+ if (RealFileExists(Final) == true)
{
string const LastGoodSig = DestFile + ".reverify";
Rename(Final,LastGoodSig);
}
}
/*}}}*/
+pkgAcqMetaClearSig::~pkgAcqMetaClearSig() /*{{{*/
+{
+ // if the file was never queued undo file-changes done in the constructor
+ if (QueueCounter == 1 && Status == StatIdle && FileSize == 0 && Complete == false)
+ {
+ string const Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
+ string const LastGoodSig = DestFile + ".reverify";
+ if (RealFileExists(Final) == false && RealFileExists(LastGoodSig) == true)
+ Rename(LastGoodSig, Final);
+ }
+}
+ /*}}}*/
// pkgAcqMetaClearSig::Custom600Headers - Insert custom request headers /*{{{*/
// ---------------------------------------------------------------------
// FIXME: this can go away once the InRelease file is used widely
diff --git a/apt-pkg/acquire-item.h b/apt-pkg/acquire-item.h
index 51d539450..10c855e63 100644
--- a/apt-pkg/acquire-item.h
+++ b/apt-pkg/acquire-item.h
@@ -774,6 +774,7 @@ class pkgAcqMetaSig : public pkgAcquire::Item
std::string MetaIndexURI, std::string MetaIndexURIDesc, std::string MetaIndexShortDesc,
const std::vector<struct IndexTarget*>* IndexTargets,
indexRecords* MetaIndexParser);
+ virtual ~pkgAcqMetaSig();
};
/*}}}*/
/** \brief An item that is responsible for downloading the meta-index {{{
@@ -904,6 +905,7 @@ public:
std::string const &MetaSigURI, std::string const &MetaSigURIDesc, std::string const &MetaSigShortDesc,
const std::vector<struct IndexTarget*>* IndexTargets,
indexRecords* MetaIndexParser);
+ virtual ~pkgAcqMetaClearSig();
};
/*}}}*/
/** \brief An item that is responsible for fetching a package file. {{{
diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc
index 85799a11b..69d4acd83 100644
--- a/apt-pkg/algorithms.cc
+++ b/apt-pkg/algorithms.cc
@@ -459,6 +459,49 @@ bool pkgAllUpgrade(pkgDepCache &Cache)
return Fix.ResolveByKeep();
}
/*}}}*/
+// AllUpgradeNoDelete - Upgrade without removing packages /*{{{*/
+// ---------------------------------------------------------------------
+/* Right now the system must be consistent before this can be called.
+ * Upgrade as much as possible without deleting anything (useful for
+ * stable systems)
+ */
+bool pkgAllUpgradeNoDelete(pkgDepCache &Cache)
+{
+ pkgDepCache::ActionGroup group(Cache);
+
+ pkgProblemResolver Fix(&Cache);
+
+ if (Cache.BrokenCount() != 0)
+ return false;
+
+ // provide the initial set of stuff we want to upgrade by marking
+ // all upgradable packages for upgrade
+ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
+ {
+ if (I->CurrentVer != 0 && Cache[I].InstallVer != 0)
+ {
+ if (_config->FindB("APT::Ignore-Hold",false) == false)
+ if (I->SelectedState == pkgCache::State::Hold)
+ continue;
+
+ Cache.MarkInstall(I, false, 0, false);
+ }
+ }
+
+ // then let auto-install loose
+ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
+ if (Cache[I].Install())
+ Cache.MarkInstall(I, true, 0, false);
+
+ // ... but it may remove stuff, we we need to clean up afterwards again
+ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
+ if (Cache[I].Delete() == true)
+ Cache.MarkKeep(I, false, false);
+
+ // resolve remaining issues via keep
+ return Fix.ResolveByKeep();
+}
+ /*}}}*/
// MinimizeUpgrade - Minimizes the set of packages to be upgraded /*{{{*/
// ---------------------------------------------------------------------
/* This simply goes over the entire set of packages and tries to keep
@@ -550,14 +593,12 @@ void pkgProblemResolver::MakeScores()
unsigned long Size = Cache.Head().PackageCount;
memset(Scores,0,sizeof(*Scores)*Size);
- // Maps to pkgCache::State::VerPriority
- // which is "Important Required Standard Optional Extra"
- // (yes, that is confusing, the order of pkgCache::State::VerPriority
- // needs to be adjusted but that requires a ABI break)
+ // maps to pkgCache::State::VerPriority:
+ // Required Important Standard Optional Extra
int PrioMap[] = {
0,
- _config->FindI("pkgProblemResolver::Scores::Important",2),
_config->FindI("pkgProblemResolver::Scores::Required",3),
+ _config->FindI("pkgProblemResolver::Scores::Important",2),
_config->FindI("pkgProblemResolver::Scores::Standard",1),
_config->FindI("pkgProblemResolver::Scores::Optional",-1),
_config->FindI("pkgProblemResolver::Scores::Extra",-2)
diff --git a/apt-pkg/algorithms.h b/apt-pkg/algorithms.h
index 7f58c8eed..a499db8ba 100644
--- a/apt-pkg/algorithms.h
+++ b/apt-pkg/algorithms.h
@@ -143,7 +143,11 @@ class pkgProblemResolver /*{{{*/
bool pkgDistUpgrade(pkgDepCache &Cache);
bool pkgApplyStatus(pkgDepCache &Cache);
bool pkgFixBroken(pkgDepCache &Cache);
+
bool pkgAllUpgrade(pkgDepCache &Cache);
+
+bool pkgAllUpgradeNoDelete(pkgDepCache &Cache);
+
bool pkgMinimizeUpgrade(pkgDepCache &Cache);
void pkgPrioSortList(pkgCache &Cache,pkgCache::Version **List);
diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc
index 37c846582..4f9b84e00 100644
--- a/apt-pkg/aptconfiguration.cc
+++ b/apt-pkg/aptconfiguration.cc
@@ -388,12 +388,12 @@ std::vector<std::string> const Configuration::getArchitectures(bool const &Cache
if (dpkgMultiArch == 0) {
close(external[0]);
std::string const chrootDir = _config->FindDir("DPkg::Chroot-Directory");
- if (chrootDir != "/" && chroot(chrootDir.c_str()) != 0)
- _error->WarningE("getArchitecture", "Couldn't chroot into %s for dpkg --print-foreign-architectures", chrootDir.c_str());
int const nullfd = open("/dev/null", O_RDONLY);
dup2(nullfd, STDIN_FILENO);
dup2(external[1], STDOUT_FILENO);
dup2(nullfd, STDERR_FILENO);
+ if (chrootDir != "/" && chroot(chrootDir.c_str()) != 0 && chdir("/") != 0)
+ _error->WarningE("getArchitecture", "Couldn't chroot into %s for dpkg --print-foreign-architectures", chrootDir.c_str());
execvp(Args[0], (char**) &Args[0]);
_error->WarningE("getArchitecture", "Can't detect foreign architectures supported by dpkg!");
_exit(100);
diff --git a/apt-pkg/cachefilter.cc b/apt-pkg/cachefilter.cc
index 64cde41d1..57b9af159 100644
--- a/apt-pkg/cachefilter.cc
+++ b/apt-pkg/cachefilter.cc
@@ -55,6 +55,17 @@ PackageNameMatchesRegEx::~PackageNameMatchesRegEx() { /*{{{*/
}
/*}}}*/
+// Fnmatch support /*{{{*/
+//----------------------------------------------------------------------
+bool PackageNameMatchesFnmatch::operator() (pkgCache::PkgIterator const &Pkg) {/*{{{*/
+ return fnmatch(Pattern.c_str(), Pkg.Name(), FNM_CASEFOLD) == 0;
+}
+ /*}}}*/
+bool PackageNameMatchesFnmatch::operator() (pkgCache::GrpIterator const &Grp) {/*{{{*/
+ return fnmatch(Pattern.c_str(), Grp.Name(), FNM_CASEFOLD) == 0;
+}
+ /*}}}*/
+
// CompleteArch to <kernel>-<cpu> tuple /*{{{*/
//----------------------------------------------------------------------
/* The complete architecture, consisting of <kernel>-<cpu>. */
diff --git a/apt-pkg/cachefilter.h b/apt-pkg/cachefilter.h
index 25cd43f47..34b7d0b46 100644
--- a/apt-pkg/cachefilter.h
+++ b/apt-pkg/cachefilter.h
@@ -14,6 +14,10 @@
/*}}}*/
namespace APT {
namespace CacheFilter {
+
+#define PACKAGE_MATCHER_ABI_COMPAT 1
+#ifdef PACKAGE_MATCHER_ABI_COMPAT
+
// PackageNameMatchesRegEx /*{{{*/
class PackageNameMatchesRegEx {
/** \brief dpointer placeholder (for later in case we need it) */
@@ -26,6 +30,19 @@ public:
~PackageNameMatchesRegEx();
};
/*}}}*/
+// PackageNameMatchesFnmatch /*{{{*/
+ class PackageNameMatchesFnmatch {
+ /** \brief dpointer placeholder (for later in case we need it) */
+ void *d;
+ const std::string Pattern;
+public:
+ PackageNameMatchesFnmatch(std::string const &Pattern)
+ : Pattern(Pattern) {};
+ bool operator() (pkgCache::PkgIterator const &Pkg);
+ bool operator() (pkgCache::GrpIterator const &Grp);
+ ~PackageNameMatchesFnmatch() {};
+};
+ /*}}}*/
// PackageArchitectureMatchesSpecification /*{{{*/
/** \class PackageArchitectureMatchesSpecification
\brief matching against architecture specification strings
@@ -55,6 +72,73 @@ public:
bool operator() (pkgCache::VerIterator const &Ver);
~PackageArchitectureMatchesSpecification();
};
+
+#else
+
+class PackageMatcher {
+ public:
+ virtual bool operator() (pkgCache::PkgIterator const &Pkg) { return false; };
+ virtual bool operator() (pkgCache::GrpIterator const &Grp) { return false; };
+ virtual bool operator() (pkgCache::VerIterator const &Ver) { return false; };
+
+ virtual ~PackageMatcher() {};
+};
+
+// PackageNameMatchesRegEx /*{{{*/
+class PackageNameMatchesRegEx : public PackageMatcher {
+ /** \brief dpointer placeholder (for later in case we need it) */
+ void *d;
+ regex_t* pattern;
+public:
+ PackageNameMatchesRegEx(std::string const &Pattern);
+ virtual bool operator() (pkgCache::PkgIterator const &Pkg);
+ virtual bool operator() (pkgCache::GrpIterator const &Grp);
+ virtual ~PackageNameMatchesRegEx();
+};
+ /*}}}*/
+// PackageNameMatchesFnmatch /*{{{*/
+ class PackageNameMatchesFnmatch : public PackageMatcher{
+ /** \brief dpointer placeholder (for later in case we need it) */
+ void *d;
+ const std::string Pattern;
+public:
+ PackageNameMatchesFnmatch(std::string const &Pattern)
+ : Pattern(Pattern) {};
+ virtual bool operator() (pkgCache::PkgIterator const &Pkg);
+ virtual bool operator() (pkgCache::GrpIterator const &Grp);
+ virtual ~PackageNameMatchesFnmatch() {};
+};
+ /*}}}*/
+// PackageArchitectureMatchesSpecification /*{{{*/
+/** \class PackageArchitectureMatchesSpecification
+ \brief matching against architecture specification strings
+
+ The strings are of the format <kernel>-<cpu> where either component,
+ or the whole string, can be the wildcard "any" as defined in
+ debian-policy §11.1 "Architecture specification strings".
+
+ Examples: i386, mipsel, linux-any, any-amd64, any */
+class PackageArchitectureMatchesSpecification : public PackageMatcher {
+ std::string literal;
+ std::string complete;
+ bool isPattern;
+ /** \brief dpointer placeholder (for later in case we need it) */
+ void *d;
+public:
+ /** \brief matching against architecture specification strings
+ *
+ * @param pattern is the architecture specification string
+ * @param isPattern defines if the given \b pattern is a
+ * architecture specification pattern to match others against
+ * or if it is the fixed string and matched against patterns
+ */
+ PackageArchitectureMatchesSpecification(std::string const &pattern, bool const isPattern = true);
+ bool operator() (char const * const &arch);
+ virtual bool operator() (pkgCache::PkgIterator const &Pkg);
+ virtual bool operator() (pkgCache::VerIterator const &Ver);
+ virtual ~PackageArchitectureMatchesSpecification();
+};
+#endif
/*}}}*/
}
}
diff --git a/apt-pkg/cacheset.cc b/apt-pkg/cacheset.cc
index 1fea4f94a..0147f7e86 100644
--- a/apt-pkg/cacheset.cc
+++ b/apt-pkg/cacheset.cc
@@ -155,6 +155,69 @@ bool PackageContainerInterface::FromRegEx(PackageContainerInterface * const pci,
return true;
}
/*}}}*/
+// FromFnmatch - Returns the package defined by this fnmatch /*{{{*/
+bool
+PackageContainerInterface::FromFnmatch(PackageContainerInterface * const pci,
+ pkgCacheFile &Cache,
+ std::string pattern,
+ CacheSetHelper &helper)
+{
+ static const char * const isfnmatch = ".?*[]!";
+ if (pattern.find_first_of(isfnmatch) == std::string::npos)
+ return false;
+
+ bool const wasEmpty = pci->empty();
+ if (wasEmpty == true)
+ pci->setConstructor(FNMATCH);
+
+ size_t archfound = pattern.find_last_of(':');
+ std::string arch = "native";
+ if (archfound != std::string::npos) {
+ arch = pattern.substr(archfound+1);
+ if (arch.find_first_of(isfnmatch) == std::string::npos)
+ pattern.erase(archfound);
+ else
+ arch = "native";
+ }
+
+ if (unlikely(Cache.GetPkgCache() == 0))
+ return false;
+
+ APT::CacheFilter::PackageNameMatchesFnmatch filter(pattern);
+
+ bool found = false;
+ for (pkgCache::GrpIterator Grp = Cache.GetPkgCache()->GrpBegin(); Grp.end() == false; ++Grp) {
+ if (filter(Grp) == false)
+ continue;
+ pkgCache::PkgIterator Pkg = Grp.FindPkg(arch);
+ if (Pkg.end() == true) {
+ if (archfound == std::string::npos) {
+ std::vector<std::string> archs = APT::Configuration::getArchitectures();
+ for (std::vector<std::string>::const_iterator a = archs.begin();
+ a != archs.end() && Pkg.end() != true; ++a)
+ Pkg = Grp.FindPkg(*a);
+ }
+ if (Pkg.end() == true)
+ continue;
+ }
+
+ pci->insert(Pkg);
+ helper.showRegExSelection(Pkg, pattern);
+ found = true;
+ }
+
+ if (found == false) {
+ helper.canNotFindRegEx(pci, Cache, pattern);
+ pci->setConstructor(UNKNOWN);
+ return false;
+ }
+
+ if (wasEmpty == false && pci->getConstructor() != UNKNOWN)
+ pci->setConstructor(UNKNOWN);
+
+ return true;
+}
+ /*}}}*/
// FromName - Returns the package defined by this string /*{{{*/
pkgCache::PkgIterator PackageContainerInterface::FromName(pkgCacheFile &Cache,
std::string const &str, CacheSetHelper &helper) {
@@ -239,6 +302,7 @@ bool PackageContainerInterface::FromString(PackageContainerInterface * const pci
if (FromGroup(pci, Cache, str, helper) == false &&
FromTask(pci, Cache, str, helper) == false &&
+ FromFnmatch(pci, Cache, str, helper) == false &&
FromRegEx(pci, Cache, str, helper) == false)
{
helper.canNotFindPackage(pci, Cache, str);
diff --git a/apt-pkg/cacheset.h b/apt-pkg/cacheset.h
index 2a45910ba..29103aad9 100644
--- a/apt-pkg/cacheset.h
+++ b/apt-pkg/cacheset.h
@@ -11,7 +11,6 @@
// Include Files /*{{{*/
#include <iostream>
#include <fstream>
-#include <list>
#include <map>
#include <set>
#include <list>
@@ -132,13 +131,14 @@ public:
virtual bool empty() const = 0;
virtual void clear() = 0;
- enum Constructor { UNKNOWN, REGEX, TASK };
+ enum Constructor { UNKNOWN, REGEX, TASK, FNMATCH };
virtual void setConstructor(Constructor const &con) = 0;
virtual Constructor getConstructor() const = 0;
static bool FromTask(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
static bool FromRegEx(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper);
+ static bool FromFnmatch(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
static bool FromGroup(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
static bool FromString(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper);
static bool FromCommandLine(PackageContainerInterface * const pci, pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper);
@@ -260,6 +260,16 @@ public: /*{{{*/
return FromRegEx(Cache, pattern, helper);
}
+ static PackageContainer FromFnmatch(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) {
+ PackageContainer cont(FNMATCH);
+ PackageContainerInterface::FromFnmatch(&cont, Cache, pattern, helper);
+ return cont;
+ }
+ static PackageContainer FromFnMatch(pkgCacheFile &Cache, std::string const &pattern) {
+ CacheSetHelper helper;
+ return FromFnmatch(Cache, pattern, helper);
+ }
+
/** \brief returns a package specified by a string
\param Cache the package is in
diff --git a/apt-pkg/cdrom.h b/apt-pkg/cdrom.h
index 4fc3d3928..7d19eb813 100644
--- a/apt-pkg/cdrom.h
+++ b/apt-pkg/cdrom.h
@@ -18,7 +18,7 @@ class pkgCdromStatus /*{{{*/
int totalSteps;
public:
- pkgCdromStatus() {};
+ pkgCdromStatus() : totalSteps(0) {};
virtual ~pkgCdromStatus() {};
// total steps
diff --git a/apt-pkg/contrib/cdromutl.cc b/apt-pkg/contrib/cdromutl.cc
index 187f6bd59..afa01a562 100644
--- a/apt-pkg/contrib/cdromutl.cc
+++ b/apt-pkg/contrib/cdromutl.cc
@@ -122,8 +122,9 @@ bool MountCdrom(string Path, string DeviceName)
if (Child == 0)
{
// Make all the fds /dev/null
+ int null_fd = open("/dev/null",O_RDWR);
for (int I = 0; I != 3; I++)
- dup2(open("/dev/null",O_RDWR),I);
+ dup2(null_fd, I);
if (_config->Exists("Acquire::cdrom::"+Path+"::Mount") == true)
{
diff --git a/apt-pkg/contrib/cmndline.cc b/apt-pkg/contrib/cmndline.cc
index 75d02cad4..2086d91ca 100644
--- a/apt-pkg/contrib/cmndline.cc
+++ b/apt-pkg/contrib/cmndline.cc
@@ -38,6 +38,42 @@ CommandLine::~CommandLine()
delete [] FileList;
}
/*}}}*/
+// CommandLine::GetCommand - return the first non-option word /*{{{*/
+char const * CommandLine::GetCommand(Dispatch const * const Map,
+ unsigned int const argc, char const * const * const argv)
+{
+ // if there is a -- on the line there must be the word we search for around it
+ // as -- marks the end of the options, just not sure if the command can be
+ // considered an option or not, so accept both
+ for (size_t i = 1; i < argc; ++i)
+ {
+ if (strcmp(argv[i], "--") != 0)
+ continue;
+ ++i;
+ if (i < argc)
+ for (size_t j = 0; Map[j].Match != NULL; ++j)
+ if (strcmp(argv[i], Map[j].Match) == 0)
+ return Map[j].Match;
+ i -= 2;
+ if (i != 0)
+ for (size_t j = 0; Map[j].Match != NULL; ++j)
+ if (strcmp(argv[i], Map[j].Match) == 0)
+ return Map[j].Match;
+ return NULL;
+ }
+ // no --, so search for the first word matching a command
+ // FIXME: How like is it that an option parameter will be also a valid Match ?
+ for (size_t i = 1; i < argc; ++i)
+ {
+ if (*(argv[i]) == '-')
+ continue;
+ for (size_t j = 0; Map[j].Match != NULL; ++j)
+ if (strcmp(argv[i], Map[j].Match) == 0)
+ return Map[j].Match;
+ }
+ return NULL;
+}
+ /*}}}*/
// CommandLine::Parse - Main action member /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -361,6 +397,7 @@ bool CommandLine::DispatchArg(Dispatch *Map,bool NoMatch)
void CommandLine::SaveInConfig(unsigned int const &argc, char const * const * const argv)
{
char cmdline[100 + argc * 50];
+ memset(cmdline, 0, sizeof(cmdline));
unsigned int length = 0;
bool lastWasOption = false;
bool closeQuote = false;
@@ -390,3 +427,15 @@ void CommandLine::SaveInConfig(unsigned int const &argc, char const * const * co
_config->Set("CommandLine::AsString", cmdline);
}
/*}}}*/
+CommandLine::Args CommandLine::MakeArgs(char ShortOpt, char const *LongOpt, char const *ConfName, unsigned long Flags)/*{{{*/
+{
+ /* In theory, this should be a constructor for CommandLine::Args instead,
+ but this breaks compatibility as gcc thinks this is a c++11 initializer_list */
+ CommandLine::Args arg;
+ arg.ShortOpt = ShortOpt;
+ arg.LongOpt = LongOpt;
+ arg.ConfName = ConfName;
+ arg.Flags = Flags;
+ return arg;
+}
+ /*}}}*/
diff --git a/apt-pkg/contrib/cmndline.h b/apt-pkg/contrib/cmndline.h
index 9f505fd41..180276633 100644
--- a/apt-pkg/contrib/cmndline.h
+++ b/apt-pkg/contrib/cmndline.h
@@ -83,6 +83,12 @@ class CommandLine
unsigned int FileSize() const;
bool DispatchArg(Dispatch *List,bool NoMatch = true);
+ static char const * GetCommand(Dispatch const * const Map,
+ unsigned int const argc, char const * const * const argv);
+
+ static CommandLine::Args MakeArgs(char ShortOpt, char const *LongOpt,
+ char const *ConfName, unsigned long Flags);
+
CommandLine(Args *AList,Configuration *Conf);
~CommandLine();
};
diff --git a/apt-pkg/contrib/configuration.cc b/apt-pkg/contrib/configuration.cc
index 808a708a1..4ef4663c0 100644
--- a/apt-pkg/contrib/configuration.cc
+++ b/apt-pkg/contrib/configuration.cc
@@ -422,6 +422,18 @@ void Configuration::Clear(string const &Name, string const &Value)
}
/*}}}*/
+// Configuration::Clear - Clear everything /*{{{*/
+// ---------------------------------------------------------------------
+void Configuration::Clear()
+{
+ const Configuration::Item *Top = Tree(0);
+ while( Top != 0 )
+ {
+ Clear(Top->FullTag());
+ Top = Top->Next;
+ }
+}
+ /*}}}*/
// Configuration::Clear - Clear an entire tree /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -811,7 +823,7 @@ bool ReadConfigFile(Configuration &Conf,const string &FName,bool const &AsSectio
// Go down a level
if (TermChar == '{')
{
- if (StackPos <= 100)
+ if (StackPos < sizeof(Stack)/sizeof(std::string))
Stack[StackPos++] = ParentTag;
/* Make sectional tags incorperate the section into the
diff --git a/apt-pkg/contrib/configuration.h b/apt-pkg/contrib/configuration.h
index ea94c2fe6..8e09ea0a6 100644
--- a/apt-pkg/contrib/configuration.h
+++ b/apt-pkg/contrib/configuration.h
@@ -94,6 +94,7 @@ class Configuration
// clear a whole tree
void Clear(const std::string &Name);
+ void Clear();
// remove a certain value from a list (e.g. the list of "APT::Keep-Fds")
void Clear(std::string const &List, std::string const &Value);
diff --git a/apt-pkg/contrib/error.cc b/apt-pkg/contrib/error.cc
index 122e2c809..d457781c3 100644
--- a/apt-pkg/contrib/error.cc
+++ b/apt-pkg/contrib/error.cc
@@ -67,9 +67,10 @@ bool GlobalError::NAME (const char *Function, const char *Description,...) { \
int const errsv = errno; \
while (true) { \
va_start(args,Description); \
- if (InsertErrno(TYPE, Function, Description, args, errsv, msgSize) == false) \
- break; \
+ bool const retry = InsertErrno(TYPE, Function, Description, args, errsv, msgSize); \
va_end(args); \
+ if (retry == false) \
+ break; \
} \
return false; \
}
@@ -88,9 +89,10 @@ bool GlobalError::InsertErrno(MsgType const &type, const char *Function,
int const errsv = errno;
while (true) {
va_start(args,Description);
- if (InsertErrno(type, Function, Description, args, errsv, msgSize) == false)
- break;
+ bool const retry = InsertErrno(type, Function, Description, args, errsv, msgSize);
va_end(args);
+ if (retry == false)
+ break;
}
return false;
}
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc
index 0f88923cf..4806ae3f9 100644
--- a/apt-pkg/contrib/fileutl.cc
+++ b/apt-pkg/contrib/fileutl.cc
@@ -41,6 +41,8 @@
#include <dirent.h>
#include <signal.h>
#include <errno.h>
+#include <glob.h>
+
#include <set>
#include <algorithm>
@@ -244,17 +246,20 @@ int GetLock(string File,bool Errors)
fl.l_len = 0;
if (fcntl(FD,F_SETLK,&fl) == -1)
{
+ // always close to not leak resources
+ int Tmp = errno;
+ close(FD);
+ errno = Tmp;
+
if (errno == ENOLCK)
{
_error->Warning(_("Not using locking for nfs mounted lock file %s"),File.c_str());
return dup(0); // Need something for the caller to close
- }
+ }
+
if (Errors == true)
_error->Errno("open",_("Could not get lock %s"),File.c_str());
- int Tmp = errno;
- close(FD);
- errno = Tmp;
return -1;
}
@@ -941,9 +946,6 @@ bool FileFd::Open(string FileName,unsigned int const Mode,APT::Configuration::Co
if ((Mode & Atomic) == Atomic)
{
Flags |= Replace;
- char *name = strdup((FileName + ".XXXXXX").c_str());
- TemporaryFileName = string(mktemp(name));
- free(name);
}
else if ((Mode & (Exclusive | Create)) == (Exclusive | Create))
{
@@ -966,11 +968,24 @@ bool FileFd::Open(string FileName,unsigned int const Mode,APT::Configuration::Co
if_FLAGGED_SET(Create, O_CREAT);
if_FLAGGED_SET(Empty, O_TRUNC);
if_FLAGGED_SET(Exclusive, O_EXCL);
- else if_FLAGGED_SET(Atomic, O_EXCL);
#undef if_FLAGGED_SET
- if (TemporaryFileName.empty() == false)
- iFd = open(TemporaryFileName.c_str(), fileflags, Perms);
+ if ((Mode & Atomic) == Atomic)
+ {
+ char *name = strdup((FileName + ".XXXXXX").c_str());
+
+ if((iFd = mkstemp(name)) == -1)
+ {
+ free(name);
+ return FileFdErrno("mkostemp", "Could not create temporary file for %s", FileName.c_str());
+ }
+
+ TemporaryFileName = string(name);
+ free(name);
+
+ if(Perms != 600 && fchmod(iFd, Perms) == -1)
+ return FileFdErrno("fchmod", "Could not change permissions for temporary file %s", TemporaryFileName.c_str());
+ }
else
iFd = open(FileName.c_str(), fileflags, Perms);
@@ -1218,11 +1233,9 @@ FileFd::~FileFd()
{
Close();
if (d != NULL)
- {
d->CloseDown(FileName);
- delete d;
- d = NULL;
- }
+ delete d;
+ d = NULL;
}
/*}}}*/
// FileFd::Read - Read a bit of the file /*{{{*/
@@ -1598,7 +1611,11 @@ unsigned long long FileFd::Size()
char ignore[1000];
unsigned long long read = 0;
do {
- Read(ignore, sizeof(ignore), &read);
+ if (Read(ignore, sizeof(ignore), &read) == false)
+ {
+ Seek(oldSeek);
+ return 0;
+ }
} while(read != 0);
size = Tell();
Seek(oldSeek);
@@ -1615,10 +1632,16 @@ unsigned long long FileFd::Size()
* bits of the file */
// FIXME: Size for gz-files is limited by 32bit… no largefile support
if (lseek(iFd, -4, SEEK_END) < 0)
- return FileFdErrno("lseek","Unable to seek to end of gzipped file");
- size = 0L;
+ {
+ FileFdErrno("lseek","Unable to seek to end of gzipped file");
+ return 0;
+ }
+ size = 0;
if (read(iFd, &size, 4) != 4)
- return FileFdErrno("read","Unable to read original size of gzipped file");
+ {
+ FileFdErrno("read","Unable to read original size of gzipped file");
+ return 0;
+ }
#ifdef WORDS_BIGENDIAN
uint32_t tmp_size = size;
@@ -1628,7 +1651,10 @@ unsigned long long FileFd::Size()
#endif
if (lseek(iFd, oldPos, SEEK_SET) < 0)
- return FileFdErrno("lseek","Unable to seek in gzipped file");
+ {
+ FileFdErrno("lseek","Unable to seek in gzipped file");
+ return 0;
+ }
return size;
}
@@ -1752,3 +1778,33 @@ bool FileFd::FileFdError(const char *Description,...) {
/*}}}*/
gzFile FileFd::gzFd() { return (gzFile) d->gz; }
+
+
+// Glob - wrapper around "glob()" /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+std::vector<std::string> Glob(std::string const &pattern, int flags)
+{
+ std::vector<std::string> result;
+ glob_t globbuf;
+ int glob_res;
+ unsigned int i;
+
+ glob_res = glob(pattern.c_str(), flags, NULL, &globbuf);
+
+ if (glob_res != 0)
+ {
+ if(glob_res != GLOB_NOMATCH) {
+ _error->Errno("glob", "Problem with glob");
+ return result;
+ }
+ }
+
+ // append results
+ for(i=0;i<globbuf.gl_pathc;i++)
+ result.push_back(string(globbuf.gl_pathv[i]));
+
+ globfree(&globbuf);
+ return result;
+}
+ /*}}}*/
diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h
index 3ec01dd9a..decd64d9d 100644
--- a/apt-pkg/contrib/fileutl.h
+++ b/apt-pkg/contrib/fileutl.h
@@ -191,4 +191,7 @@ std::string flNoLink(std::string File);
std::string flExtension(std::string File);
std::string flCombine(std::string Dir,std::string File);
+// simple c++ glob
+std::vector<std::string> Glob(std::string const &pattern, int flags=0);
+
#endif
diff --git a/apt-pkg/contrib/sha2.h b/apt-pkg/contrib/sha2.h
index 51c921dbd..8e0c99a1b 100644
--- a/apt-pkg/contrib/sha2.h
+++ b/apt-pkg/contrib/sha2.h
@@ -60,10 +60,11 @@ class SHA256Summation : public SHA2SummationBase
res.Set(Sum);
return res;
};
- SHA256Summation()
+ SHA256Summation()
{
SHA256_Init(&ctx);
Done = false;
+ memset(&Sum, 0, sizeof(Sum));
};
};
@@ -96,6 +97,7 @@ class SHA512Summation : public SHA2SummationBase
{
SHA512_Init(&ctx);
Done = false;
+ memset(&Sum, 0, sizeof(Sum));
};
};
diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc
index d0e74d8c5..0955b69f7 100644
--- a/apt-pkg/contrib/strutl.cc
+++ b/apt-pkg/contrib/strutl.cc
@@ -943,6 +943,8 @@ bool StrToTime(const string &Val,time_t &Result)
Tm.tm_isdst = 0;
if (Month[0] != 0)
Tm.tm_mon = MonthConv(Month);
+ else
+ Tm.tm_mon = 0; // we don't have a month, so pick something
Tm.tm_year -= 1900;
// Convert to local time and then to GMT
@@ -1233,12 +1235,12 @@ char *safe_snprintf(char *Buffer,char *End,const char *Format,...)
va_list args;
int Did;
- va_start(args,Format);
-
if (End <= Buffer)
return End;
-
+ va_start(args,Format);
Did = vsnprintf(Buffer,End - Buffer,Format,args);
+ va_end(args);
+
if (Did < 0 || Buffer + Did > End)
return End;
return Buffer + Did;
@@ -1291,6 +1293,18 @@ bool CheckDomainList(const string &Host,const string &List)
return false;
}
/*}}}*/
+// strv_length - Return the length of a NULL-terminated string array /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+size_t strv_length(const char **str_array)
+{
+ size_t i;
+ for (i=0; str_array[i] != NULL; i++)
+ /* nothing */
+ ;
+ return i;
+}
+
// DeEscapeString - unescape (\0XX and \xXX) from a string /*{{{*/
// ---------------------------------------------------------------------
/* */
diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h
index e92f91dc0..530896141 100644
--- a/apt-pkg/contrib/strutl.h
+++ b/apt-pkg/contrib/strutl.h
@@ -108,6 +108,10 @@ inline int stringcasecmp(std::string::const_iterator A,std::string::const_iterat
APT_MKSTRCMP2(stringcmp,stringcmp);
APT_MKSTRCMP2(stringcasecmp,stringcasecmp);
+// Return the length of a NULL-terminated string array
+size_t strv_length(const char **str_array);
+
+
inline const char *DeNull(const char *s) {return (s == 0?"(null)":s);};
class URI
diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc
index 28857176b..87aab6ee2 100644
--- a/apt-pkg/deb/deblistparser.cc
+++ b/apt-pkg/deb/deblistparser.cc
@@ -805,94 +805,28 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,
map_ptrloc const storage = WriteUniqString(component);
FileI->Component = storage;
- // FIXME: should use FileFd and TagSection
- FILE* release = fdopen(dup(File.Fd()), "r");
- if (release == NULL)
+ pkgTagFile TagFile(&File, File.Size());
+ pkgTagSection Section;
+ if (_error->PendingError() == true || TagFile.Step(Section) == false)
return false;
- char buffer[101];
- while (fgets(buffer, sizeof(buffer), release) != NULL)
- {
- size_t len = 0;
-
- // Skip empty lines
- for (; buffer[len] == '\r' && buffer[len] == '\n'; ++len)
- /* nothing */
- ;
- if (buffer[len] == '\0')
- continue;
-
- // seperate the tag from the data
- const char* dataStart = strchr(buffer + len, ':');
- if (dataStart == NULL)
- continue;
- len = dataStart - buffer;
- for (++dataStart; *dataStart == ' '; ++dataStart)
- /* nothing */
- ;
- const char* dataEnd = (const char*)rawmemchr(dataStart, '\0');
- // The last char should be a newline, but we can never be sure: #633350
- const char* lineEnd = dataEnd;
- for (--lineEnd; *lineEnd == '\r' || *lineEnd == '\n'; --lineEnd)
- /* nothing */
- ;
- ++lineEnd;
-
- // which datastorage need to be updated
- enum { Suite, Component, Version, Origin, Codename, Label, None } writeTo = None;
- if (buffer[0] == ' ')
- ;
- #define APT_PARSER_WRITETO(X) else if (strncmp(#X, buffer, len) == 0) writeTo = X;
- APT_PARSER_WRITETO(Suite)
- APT_PARSER_WRITETO(Component)
- APT_PARSER_WRITETO(Version)
- APT_PARSER_WRITETO(Origin)
- APT_PARSER_WRITETO(Codename)
- APT_PARSER_WRITETO(Label)
- #undef APT_PARSER_WRITETO
- #define APT_PARSER_FLAGIT(X) else if (strncmp(#X, buffer, len) == 0) \
- pkgTagSection::FindFlag(FileI->Flags, pkgCache::Flag:: X, dataStart, lineEnd);
- APT_PARSER_FLAGIT(NotAutomatic)
- APT_PARSER_FLAGIT(ButAutomaticUpgrades)
- #undef APT_PARSER_FLAGIT
-
- // load all data from the line and save it
- string data;
- if (writeTo != None)
- data.append(dataStart, dataEnd);
- if (sizeof(buffer) - 1 == (dataEnd - buffer))
- {
- while (fgets(buffer, sizeof(buffer), release) != NULL)
- {
- if (writeTo != None)
- data.append(buffer);
- if (strlen(buffer) != sizeof(buffer) - 1)
- break;
- }
- }
- if (writeTo != None)
- {
- // remove spaces and stuff from the end of the data line
- for (std::string::reverse_iterator s = data.rbegin();
- s != data.rend(); ++s)
- {
- if (*s != '\r' && *s != '\n' && *s != ' ')
- break;
- *s = '\0';
- }
- map_ptrloc const storage = WriteUniqString(data);
- switch (writeTo) {
- case Suite: FileI->Archive = storage; break;
- case Component: FileI->Component = storage; break;
- case Version: FileI->Version = storage; break;
- case Origin: FileI->Origin = storage; break;
- case Codename: FileI->Codename = storage; break;
- case Label: FileI->Label = storage; break;
- case None: break;
- }
- }
+ std::string data;
+ #define APT_INRELEASE(TAG, STORE) \
+ data = Section.FindS(TAG); \
+ if (data.empty() == false) \
+ { \
+ map_ptrloc const storage = WriteUniqString(data); \
+ STORE = storage; \
}
- fclose(release);
+ APT_INRELEASE("Suite", FileI->Archive)
+ APT_INRELEASE("Component", FileI->Component)
+ APT_INRELEASE("Version", FileI->Version)
+ APT_INRELEASE("Origin", FileI->Origin)
+ APT_INRELEASE("Codename", FileI->Codename)
+ APT_INRELEASE("Label", FileI->Label)
+ #undef APT_INRELEASE
+ Section.FindFlag("NotAutomatic", FileI->Flags, pkgCache::Flag::NotAutomatic);
+ Section.FindFlag("ButAutomaticUpgrades", FileI->Flags, pkgCache::Flag::ButAutomaticUpgrades);
return !_error->PendingError();
}
diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc
index 7dd5ab2bf..b597b6f3c 100644
--- a/apt-pkg/deb/debmetaindex.cc
+++ b/apt-pkg/deb/debmetaindex.cc
@@ -238,6 +238,7 @@ bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll) const
new pkgAcqIndex(Owner, (*Target)->URI, (*Target)->Description,
(*Target)->ShortDesc, HashString());
}
+ delete targets;
// this is normally created in pkgAcqMetaSig, but if we run
// in --print-uris mode, we add it here
diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc
index 3fb80d158..3c1013761 100644
--- a/apt-pkg/deb/dpkgpm.cc
+++ b/apt-pkg/deb/dpkgpm.cc
@@ -134,6 +134,8 @@ static void dpkgChrootDirectory()
std::cerr << "Chrooting into " << chrootDir << std::endl;
if (chroot(chrootDir.c_str()) != 0)
_exit(100);
+ if (chdir("/") != 0)
+ _exit(100);
}
/*}}}*/
@@ -294,7 +296,7 @@ bool pkgDPkgPM::SendPkgsInfo(FILE * const F, unsigned int const &Version)
if (CurVer.end() == true && (I->Op == Item::Remove || I->Op == Item::Purge))
CurVer = FindNowVersion(I->Pkg);
- else if (CurVer.end() == true)
+ if (CurVer.end() == true)
{
if (Version <= 2)
fprintf(F, "- ");
@@ -380,24 +382,32 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf)
OptSec = "DPkg::Tools::Options::" + string(Opts->Value.c_str(),Pos);
unsigned int Version = _config->FindI(OptSec+"::Version",1);
+ unsigned int InfoFD = _config->FindI(OptSec + "::InfoFD", STDIN_FILENO);
// Create the pipes
int Pipes[2];
if (pipe(Pipes) != 0)
return _error->Errno("pipe","Failed to create IPC pipe to subprocess");
- SetCloseExec(Pipes[0],true);
+ if (InfoFD != (unsigned)Pipes[0])
+ SetCloseExec(Pipes[0],true);
+ else
+ _config->Set("APT::Keep-Fds::", Pipes[0]);
SetCloseExec(Pipes[1],true);
-
+
// Purified Fork for running the script
- pid_t Process = ExecFork();
+ pid_t Process = ExecFork();
if (Process == 0)
{
// Setup the FDs
- dup2(Pipes[0],STDIN_FILENO);
+ dup2(Pipes[0], InfoFD);
SetCloseExec(STDOUT_FILENO,false);
- SetCloseExec(STDIN_FILENO,false);
+ SetCloseExec(STDIN_FILENO,false);
SetCloseExec(STDERR_FILENO,false);
+ string hookfd;
+ strprintf(hookfd, "%d", InfoFD);
+ setenv("APT_HOOK_INFO_FD", hookfd.c_str(), 1);
+
dpkgChrootDirectory();
const char *Args[4];
Args[0] = "/bin/sh";
@@ -407,6 +417,8 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf)
execv(Args[0],(char **)Args);
_exit(100);
}
+ if (InfoFD == (unsigned)Pipes[0])
+ _config->Clear("APT::Keep-Fds", Pipes[0]);
close(Pipes[0]);
FILE *F = fdopen(Pipes[1],"w");
if (F == 0)
@@ -752,13 +764,15 @@ bool pkgDPkgPM::OpenLog()
return _error->WarningE("OpenLog", _("Could not open file '%s'"), logfile_name.c_str());
setvbuf(d->term_out, NULL, _IONBF, 0);
SetCloseExec(fileno(d->term_out), true);
- struct passwd *pw;
- struct group *gr;
- pw = getpwnam("root");
- gr = getgrnam("adm");
- if (pw != NULL && gr != NULL)
- chown(logfile_name.c_str(), pw->pw_uid, gr->gr_gid);
- chmod(logfile_name.c_str(), 0640);
+ if (getuid() == 0) // if we aren't root, we can't chown a file, so don't try it
+ {
+ struct passwd *pw = getpwnam("root");
+ struct group *gr = getgrnam("adm");
+ if (pw != NULL && gr != NULL && chown(logfile_name.c_str(), pw->pw_uid, gr->gr_gid) != 0)
+ _error->WarningE("OpenLog", "chown to root:adm of file %s failed", logfile_name.c_str());
+ }
+ if (chmod(logfile_name.c_str(), 0640) != 0)
+ _error->WarningE("OpenLog", "chmod 0640 of file %s failed", logfile_name.c_str());
fprintf(d->term_out, "\nLog started: %s\n", timestr);
}
@@ -1249,16 +1263,13 @@ bool pkgDPkgPM::Go(int OutStatusFd)
// if tcgetattr does not return zero there was a error
// and we do not do any pty magic
- if (tcgetattr(0, &tt) == 0)
+ _error->PushToStack();
+ if (tcgetattr(STDOUT_FILENO, &tt) == 0)
{
ioctl(0, TIOCGWINSZ, (char *)&win);
- if (openpty(&master, &slave, NULL, &tt, &win) < 0)
+ 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(d->term_out)
- fprintf(d->term_out, "%s",s);
+ _error->Errno("openpty", _("Can not write log (%s)"), _("Is /dev/pts mounted?"));
master = slave = -1;
} else {
struct termios rtt;
@@ -1276,6 +1287,15 @@ bool pkgDPkgPM::Go(int OutStatusFd)
sigprocmask(SIG_SETMASK, &original_sigmask, 0);
}
}
+ // complain only if stdout is either a terminal (but still failed) or is an invalid
+ // descriptor otherwise we would complain about redirection to e.g. /dev/null as well.
+ else if (isatty(STDOUT_FILENO) == 1 || errno == EBADF)
+ _error->Errno("tcgetattr", _("Can not write log (%s)"), _("Is stdout a terminal?"));
+
+ if (_error->PendingError() == true)
+ _error->DumpErrors(std::cerr);
+ _error->RevertToStack();
+
// Fork dpkg
pid_t Child;
_config->Set("APT::Keep-Fds::",fd[1]);
diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc
index 2c6eb43bf..978a893f7 100644
--- a/apt-pkg/depcache.cc
+++ b/apt-pkg/depcache.cc
@@ -1007,9 +1007,6 @@ struct CompareProviders {
else if ((B->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important)
return true;
}
- // higher priority seems like a good idea
- if (AV->Priority != BV->Priority)
- return AV->Priority > BV->Priority;
// prefer native architecture
if (strcmp(A.Arch(), B.Arch()) != 0)
{
@@ -1024,6 +1021,9 @@ struct CompareProviders {
else if (*a == B.Arch())
return true;
}
+ // higher priority seems like a good idea
+ if (AV->Priority != BV->Priority)
+ return AV->Priority > BV->Priority;
// unable to decide…
return A->ID < B->ID;
}
diff --git a/apt-pkg/indexcopy.cc b/apt-pkg/indexcopy.cc
index 1d61b974d..7694cb1dd 100644
--- a/apt-pkg/indexcopy.cc
+++ b/apt-pkg/indexcopy.cc
@@ -106,9 +106,9 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List,
} else {
Target.Open(TargetF,FileFd::WriteAtomic);
}
- FILE *TargetFl = fdopen(dup(Target.Fd()),"w");
if (_error->PendingError() == true)
return false;
+ FILE *TargetFl = fdopen(dup(Target.Fd()),"w");
if (TargetFl == 0)
return _error->Errno("fdopen","Failed to reopen fd");
@@ -601,6 +601,7 @@ bool SigVerify::CopyAndVerify(string CDROM,string Name,vector<string> &SigList,
(useInRelease ? inrelease.c_str() : releasegpg.c_str()));
// something went wrong, don't copy the Release.gpg
// FIXME: delete any existing gpg file?
+ delete MetaIndex;
continue;
}
@@ -714,9 +715,9 @@ bool TranslationsCopy::CopyTranslations(string CDROM,string Name, /*{{{*/
} else {
Target.Open(TargetF,FileFd::WriteAtomic);
}
- FILE *TargetFl = fdopen(dup(Target.Fd()),"w");
if (_error->PendingError() == true)
return false;
+ FILE *TargetFl = fdopen(dup(Target.Fd()),"w");
if (TargetFl == 0)
return _error->Errno("fdopen","Failed to reopen fd");
diff --git a/apt-pkg/indexrecords.cc b/apt-pkg/indexrecords.cc
index e37a78cfb..8a72ca151 100644
--- a/apt-pkg/indexrecords.cc
+++ b/apt-pkg/indexrecords.cc
@@ -62,7 +62,7 @@ bool indexRecords::Load(const string Filename) /*{{{*/
if (OpenMaybeClearSignedFile(Filename, Fd) == false)
return false;
- pkgTagFile TagFile(&Fd, Fd.Size() + 256); // XXX
+ pkgTagFile TagFile(&Fd, Fd.Size());
if (_error->PendingError() == true)
{
strprintf(ErrorText, _("Unable to parse Release file %s"),Filename.c_str());
@@ -71,16 +71,11 @@ bool indexRecords::Load(const string Filename) /*{{{*/
pkgTagSection Section;
const char *Start, *End;
- // Skip over sections beginning with ----- as this is an idicator for clearsigns
- do {
- if (TagFile.Step(Section) == false)
- {
- strprintf(ErrorText, _("No sections in Release file %s"), Filename.c_str());
- return false;
- }
-
- Section.Get (Start, End, 0);
- } while (End - Start > 5 && strncmp(Start, "-----", 5) == 0);
+ if (TagFile.Step(Section) == false)
+ {
+ strprintf(ErrorText, _("No sections in Release file %s"), Filename.c_str());
+ return false;
+ }
Suite = Section.FindS("Suite");
Dist = Section.FindS("Codename");
diff --git a/apt-pkg/policy.cc b/apt-pkg/policy.cc
index 4ae3b5f87..0a06cc6e3 100644
--- a/apt-pkg/policy.cc
+++ b/apt-pkg/policy.cc
@@ -166,11 +166,15 @@ pkgCache::VerIterator pkgPolicy::GetCandidateVer(pkgCache::PkgIterator const &Pk
tracks the default when the default is taken away, and a permanent
pin that stays at that setting.
*/
+ bool PrefSeen = false;
for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; ++Ver)
{
/* Lets see if this version is the installed version */
bool instVer = (Pkg.CurrentVer() == Ver);
+ if (Pref == Ver)
+ PrefSeen = true;
+
for (pkgCache::VerFileIterator VF = Ver.FileList(); VF.end() == false; ++VF)
{
/* If this is the status file, and the current version is not the
@@ -187,26 +191,33 @@ pkgCache::VerIterator pkgPolicy::GetCandidateVer(pkgCache::PkgIterator const &Pk
{
Pref = Ver;
Max = Prio;
+ PrefSeen = true;
}
if (Prio > MaxAlt)
{
PrefAlt = Ver;
MaxAlt = Prio;
- }
- }
-
+ }
+ }
+
if (instVer == true && Max < 1000)
{
+ /* Not having seen the Pref yet means we have a specific pin below 1000
+ on a version below the current installed one, so ignore the specific pin
+ as this would be a downgrade otherwise */
+ if (PrefSeen == false || Pref.end() == true)
+ {
+ Pref = Ver;
+ PrefSeen = true;
+ }
/* Elevate our current selection (or the status file itself)
to the Pseudo-status priority. */
- if (Pref.end() == true)
- Pref = Ver;
Max = 1000;
-
+
// Fast path optimize.
if (StatusOverride == false)
break;
- }
+ }
}
// If we do not find our candidate, use the one with the highest pin.
// This means that if there is a version available with pin > 0; there
diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc
index 1c79ee74f..b91e868e2 100644
--- a/apt-pkg/tagfile.cc
+++ b/apt-pkg/tagfile.cc
@@ -50,21 +50,27 @@ public:
/* */
pkgTagFile::pkgTagFile(FileFd *pFd,unsigned long long Size)
{
+ /* The size is increased by 4 because if we start with the Size of the
+ filename we need to try to read 1 char more to see an EOF faster, 1
+ char the end-pointer can be on and maybe 2 newlines need to be added
+ to the end of the file -> 4 extra chars */
+ Size += 4;
d = new pkgTagFilePrivate(pFd, Size);
if (d->Fd.IsOpen() == false)
- {
d->Start = d->End = d->Buffer = 0;
+ else
+ d->Buffer = (char*)malloc(sizeof(char) * Size);
+
+ if (d->Buffer == NULL)
d->Done = true;
- d->iOffset = 0;
- return;
- }
-
- d->Buffer = new char[Size];
+ else
+ d->Done = false;
+
d->Start = d->End = d->Buffer;
- d->Done = false;
d->iOffset = 0;
- Fill();
+ if (d->Done == false)
+ Fill();
}
/*}}}*/
// TagFile::~pkgTagFile - Destructor /*{{{*/
@@ -72,11 +78,11 @@ pkgTagFile::pkgTagFile(FileFd *pFd,unsigned long long Size)
/* */
pkgTagFile::~pkgTagFile()
{
- delete [] d->Buffer;
+ free(d->Buffer);
delete d;
}
/*}}}*/
-// TagFile::Offset - Return the current offset in the buffer /*{{{*/
+// TagFile::Offset - Return the current offset in the buffer /*{{{*/
unsigned long pkgTagFile::Offset()
{
return d->iOffset;
@@ -89,19 +95,22 @@ unsigned long pkgTagFile::Offset()
*/
bool pkgTagFile::Resize()
{
- char *tmp;
- unsigned long long EndSize = d->End - d->Start;
-
// fail is the buffer grows too big
if(d->Size > 1024*1024+1)
return false;
+ return Resize(d->Size * 2);
+}
+bool pkgTagFile::Resize(unsigned long long const newSize)
+{
+ unsigned long long const EndSize = d->End - d->Start;
+
// get new buffer and use it
- tmp = new char[2*d->Size];
- memcpy(tmp, d->Buffer, d->Size);
- d->Size = d->Size*2;
- delete [] d->Buffer;
- d->Buffer = tmp;
+ char* newBuffer = (char*)realloc(d->Buffer, sizeof(char) * newSize);
+ if (newBuffer == NULL)
+ return false;
+ d->Buffer = newBuffer;
+ d->Size = newSize;
// update the start/end pointers to the new buffer
d->Start = d->Buffer;
@@ -152,9 +161,10 @@ bool pkgTagFile::Fill()
if (d->Done == false)
{
// See if only a bit of the file is left
- if (d->Fd.Read(d->End, d->Size - (d->End - d->Buffer),&Actual) == false)
+ unsigned long long const dataSize = d->Size - ((d->End - d->Buffer) + 1);
+ if (d->Fd.Read(d->End, dataSize, &Actual) == false)
return false;
- if (Actual != d->Size - (d->End - d->Buffer))
+ if (Actual != dataSize || d->Fd.Eof() == true)
d->Done = true;
d->End += Actual;
}
@@ -171,8 +181,13 @@ bool pkgTagFile::Fill()
for (const char *E = d->End - 1; E - d->End < 6 && (*E == '\n' || *E == '\r'); E--)
if (*E == '\n')
LineCount++;
- for (; LineCount < 2; LineCount++)
- *d->End++ = '\n';
+ if (LineCount < 2)
+ {
+ if ((unsigned)(d->End - d->Buffer) >= d->Size)
+ Resize(d->Size + 3);
+ for (; LineCount < 2; LineCount++)
+ *d->End++ = '\n';
+ }
return true;
}
@@ -218,6 +233,16 @@ bool pkgTagFile::Jump(pkgTagSection &Tag,unsigned long long Offset)
return true;
}
/*}}}*/
+// pkgTagSection::pkgTagSection - Constructor /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+pkgTagSection::pkgTagSection()
+ : Section(0), TagCount(0), d(NULL), Stop(0)
+{
+ memset(&Indexes, 0, sizeof(Indexes));
+ memset(&AlphaIndexes, 0, sizeof(AlphaIndexes));
+}
+ /*}}}*/
// TagSection::Scan - Scan for the end of the header information /*{{{*/
// ---------------------------------------------------------------------
/* This looks for the first double new line in the data stream.
diff --git a/apt-pkg/tagfile.h b/apt-pkg/tagfile.h
index 4718f5101..518d3dbcd 100644
--- a/apt-pkg/tagfile.h
+++ b/apt-pkg/tagfile.h
@@ -84,7 +84,7 @@ class pkgTagSection
Stop = this->Stop;
};
- pkgTagSection() : Section(0), TagCount(0), Stop(0) {};
+ pkgTagSection();
virtual ~pkgTagSection() {};
};
@@ -95,6 +95,7 @@ class pkgTagFile
bool Fill();
bool Resize();
+ bool Resize(unsigned long long const newSize);
public:
diff --git a/apt-pkg/vendorlist.cc b/apt-pkg/vendorlist.cc
index ecfc7db87..602425624 100644
--- a/apt-pkg/vendorlist.cc
+++ b/apt-pkg/vendorlist.cc
@@ -66,7 +66,7 @@ bool pkgVendorList::CreateList(Configuration& Cnf) /*{{{*/
Configuration Block(Top);
string VendorID = Top->Tag;
vector <struct Vendor::Fingerprint *> *Fingerprints = new vector<Vendor::Fingerprint *>;
- struct Vendor::Fingerprint *Fingerprint = new struct Vendor::Fingerprint;
+ struct Vendor::Fingerprint *Fingerprint = new struct Vendor::Fingerprint();
string Origin = Block.Find("Origin");
Fingerprint->Print = Block.Find("Fingerprint");