summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/CMakeLists.txt2
-rw-r--r--apt-pkg/acquire-item.cc21
-rw-r--r--apt-pkg/acquire.cc21
-rw-r--r--apt-pkg/aptconfiguration.cc2
-rw-r--r--apt-pkg/cachefile.cc18
-rw-r--r--apt-pkg/cacheiterators.h33
-rw-r--r--apt-pkg/contrib/error.cc9
-rw-r--r--apt-pkg/contrib/error.h20
-rw-r--r--apt-pkg/contrib/fileutl.cc9
-rw-r--r--apt-pkg/contrib/fileutl.h22
-rw-r--r--apt-pkg/contrib/hashes.cc4
-rw-r--r--apt-pkg/contrib/macros.h2
-rw-r--r--apt-pkg/contrib/mmap.cc29
-rw-r--r--apt-pkg/contrib/mmap.h2
-rw-r--r--apt-pkg/contrib/progress.cc2
-rw-r--r--apt-pkg/contrib/srvrec.cc5
-rw-r--r--apt-pkg/contrib/string_view.h13
-rw-r--r--apt-pkg/contrib/strutl.h21
-rw-r--r--apt-pkg/deb/debindexfile.cc6
-rw-r--r--apt-pkg/deb/deblistparser.cc57
-rw-r--r--apt-pkg/deb/deblistparser.h1
-rw-r--r--apt-pkg/deb/debmetaindex.cc14
-rw-r--r--apt-pkg/deb/debmetaindex.h4
-rw-r--r--apt-pkg/deb/debrecords.cc21
-rw-r--r--apt-pkg/deb/debrecords.h2
-rw-r--r--apt-pkg/deb/debsrcrecords.cc2
-rw-r--r--apt-pkg/deb/dpkgpm.cc9
-rw-r--r--apt-pkg/edsp.cc4
-rw-r--r--apt-pkg/endian.h118
-rw-r--r--apt-pkg/getservbyport_r.cc59
-rw-r--r--apt-pkg/indexcopy.cc2
-rw-r--r--apt-pkg/init.cc2
-rw-r--r--apt-pkg/memrchr.cc157
-rw-r--r--apt-pkg/missing.h26
-rw-r--r--apt-pkg/nameser_compat.h187
-rw-r--r--apt-pkg/pkgcache.cc1
-rw-r--r--apt-pkg/pkgcache.h20
-rw-r--r--apt-pkg/pkgcachegen.cc110
-rw-r--r--apt-pkg/pkgcachegen.h5
-rw-r--r--apt-pkg/pkgrecords.h4
-rw-r--r--apt-pkg/policy.cc3
-rw-r--r--apt-pkg/rawmemchr.cc139
-rw-r--r--apt-pkg/strchrnul.cc147
-rw-r--r--apt-pkg/tagfile.cc435
-rw-r--r--apt-pkg/tagfile.h21
45 files changed, 1285 insertions, 506 deletions
diff --git a/apt-pkg/CMakeLists.txt b/apt-pkg/CMakeLists.txt
index ce73c6a34..318c6d798 100644
--- a/apt-pkg/CMakeLists.txt
+++ b/apt-pkg/CMakeLists.txt
@@ -37,7 +37,7 @@ file(GLOB_RECURSE headers "*.h")
# Create a library using the C++ files
add_library(apt-pkg SHARED ${library})
-add_dependencies(apt-pkg apt-pkg-versionscript)
+#add_dependencies(apt-pkg apt-pkg-versionscript)
# Link the library and set the SONAME
target_include_directories(apt-pkg
PRIVATE ${ZLIB_INCLUDE_DIRS}
diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc
index bb3bc1b56..fbd561107 100644
--- a/apt-pkg/acquire-item.cc
+++ b/apt-pkg/acquire-item.cc
@@ -257,7 +257,7 @@ static bool APT_NONNULL(3, 4, 5) AllowInsecureRepositories(InsecureType const ms
if (TargetIsAllowedToBe(TransactionManager->Target, msg) == true)
{
- MessageInsecureRepository(false, msgstr, repo);
+ //MessageInsecureRepository(false, msgstr, repo);
return true;
}
@@ -1455,7 +1455,6 @@ bool pkgAcqMetaBase::CheckDownloadDone(pkgAcqTransactionItem * const I, const st
{
// for simplicity, the transaction manager is always InRelease
// even if it doesn't exist.
- TransactionManager->IMSHit = true;
I->PartialFile = I->DestFile = I->GetFinalFilename();
}
@@ -1608,7 +1607,7 @@ void pkgAcqMetaClearSig::QueueIndexes(bool const verify) /*{{{*/
}
// optional targets that we do not have in the Release file are skipped
- if (hasHashes == true && Target.IsOptional)
+ if (Target.IsOptional)
{
new CleanupItem(Owner, TransactionManager, Target);
continue;
@@ -1724,6 +1723,13 @@ void pkgAcqMetaClearSig::QueueIndexes(bool const verify) /*{{{*/
}
else
{
+ // if the source wanted these files they should have given us a release file :/
+ if (Target.IsOptional)
+ {
+ new CleanupItem(Owner, TransactionManager, Target);
+ continue;
+ }
+
// if we have no file to patch, no point in trying
trypdiff &= (GetExistingFilename(GetFinalFileNameFromURI(Target.URI)).empty() == false);
}
@@ -3275,6 +3281,8 @@ void pkgAcqIndex::StageDownloadDone(string const &Message)
{
// copy FinalFile into partial/ so that we check the hash again
string const FinalFile = GetExistingFilename(GetFinalFileNameFromURI(Target.URI));
+ DestFile = GetKeepCompressedFileName(GetPartialFileNameFromURI(Target.URI), Target);
+ unlink(DestFile.c_str());
if (symlink(FinalFile.c_str(), DestFile.c_str()) != 0)
_error->WarningE("pkgAcqIndex::StageDownloadDone", "Symlinking final file %s back to %s failed", FinalFile.c_str(), DestFile.c_str());
else
@@ -3283,7 +3291,10 @@ void pkgAcqIndex::StageDownloadDone(string const &Message)
Filename = DestFile;
}
Stage = STAGE_DECOMPRESS_AND_VERIFY;
- Desc.URI = "store:" + Filename;
+ if (Filename != DestFile && flExtension(Filename) == flExtension(DestFile))
+ Desc.URI = "copy:" + Filename;
+ else
+ Desc.URI = "store:" + Filename;
QueueURI(Desc);
SetActiveSubprocess(::URI(Desc.URI).Access);
return;
@@ -3782,7 +3793,7 @@ std::string pkgAcqChangelog::URITemplate(pkgCache::RlsFileIterator const &Rls)
should be so this could produce request order-dependent anomalies */
if (OpenMaybeClearSignedFile(Rls.FileName(), rf) == true)
{
- pkgTagFile TagFile(&rf, rf.Size());
+ pkgTagFile TagFile(&rf);
pkgTagSection Section;
if (TagFile.Step(Section) == true)
server = Section.FindS("Changelogs");
diff --git a/apt-pkg/acquire.cc b/apt-pkg/acquire.cc
index 541785b03..6a6167f3b 100644
--- a/apt-pkg/acquire.cc
+++ b/apt-pkg/acquire.cc
@@ -450,6 +450,24 @@ string pkgAcquire::QueueName(string Uri,MethodConfig const *&Config)
} else
{
FullQueueName = AccessSchema + U.Host;
+
+ int parallel(_config->FindI("Acquire::"+U.Access+"::MaxParallel",8));
+ if (parallel > 0) {
+ typedef map<string, int> indexmap;
+ static indexmap indices;
+
+ pair<indexmap::iterator, bool> cache(indices.insert(indexmap::value_type(FullQueueName, -1)));
+ if (cache.second || cache.first->second == -1) {
+ int &index(indices[U.Access]);
+ if (index >= parallel)
+ index = 0;
+ cache.first->second = index++;
+ }
+
+ ostringstream value;
+ value << U.Access << "::" << cache.first->second;
+ FullQueueName = value.str();
+ }
}
unsigned int Instances = 0, SchemaLength = AccessSchema.length();
@@ -609,7 +627,6 @@ static void CheckDropPrivsMustBeDisabled(pkgAcquire const &Fetcher)
struct passwd const * const pw = getpwnam(SandboxUser.c_str());
if (pw == NULL)
{
- _error->Warning(_("No sandbox user '%s' on the system, can not drop privileges"), SandboxUser.c_str());
_config->Set("APT::Sandbox::User", "");
return;
}
@@ -1262,7 +1279,7 @@ static struct timeval GetTimevalFromSteadyClock()
auto const Time = std::chrono::steady_clock::now().time_since_epoch();
auto const Time_sec = std::chrono::duration_cast<std::chrono::seconds>(Time);
auto const Time_usec = std::chrono::duration_cast<std::chrono::microseconds>(Time - Time_sec);
- return { Time_sec.count(), Time_usec.count() };
+ return { static_cast<time_t>(Time_sec.count()), static_cast<suseconds_t>(Time_usec.count()) };
}
bool pkgAcquireStatus::Pulse(pkgAcquire *Owner)
{
diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc
index 61e53ec3a..d4e90bba1 100644
--- a/apt-pkg/aptconfiguration.cc
+++ b/apt-pkg/aptconfiguration.cc
@@ -200,7 +200,7 @@ std::vector<std::string> const Configuration::getLanguages(bool const &All,
// FIXME: Remove support for the old APT::Acquire::Translation
// it was undocumented and so it should be not very widthly used
string const oldAcquire = _config->Find("APT::Acquire::Translation","");
- if (oldAcquire.empty() == false && oldAcquire != "environment") {
+ if (oldAcquire.empty() == false && oldAcquire != "environment" && !_config->Exists("Acquire::Languages")) {
// TRANSLATORS: the two %s are APT configuration options
_error->Notice("Option '%s' is deprecated. Please use '%s' instead, see 'man 5 apt.conf' for details.",
"APT::Acquire::Translation", "Acquire::Languages");
diff --git a/apt-pkg/cachefile.cc b/apt-pkg/cachefile.cc
index 9a1a6cfa9..8168a9af3 100644
--- a/apt-pkg/cachefile.cc
+++ b/apt-pkg/cachefile.cc
@@ -97,7 +97,7 @@ bool pkgCacheFile::BuildCaches(OpProgress *Progress, bool WithLock)
return false;
Cache.reset(new pkgCache(Map.get()));
if (_error->PendingError() == true)
- return false;
+ return _error->ReturnError();
this->Cache = Cache.release();
this->Map = Map.release();
@@ -112,7 +112,7 @@ bool pkgCacheFile::BuildCaches(OpProgress *Progress, bool WithLock)
}
if (_error->PendingError() == true)
- return false;
+ return _error->ReturnError();
if (BuildSourceList(Progress) == false)
return false;
@@ -128,14 +128,8 @@ bool pkgCacheFile::BuildCaches(OpProgress *Progress, bool WithLock)
if (Res == false)
return _error->Error(_("The package lists or status file could not be parsed or opened."));
- /* This sux, remove it someday */
- if (_error->PendingError() == true)
- _error->Warning(_("You may want to run apt-get update to correct these problems"));
-
if (Cache == nullptr)
Cache.reset(new pkgCache(Map.get()));
- if (_error->PendingError() == true)
- return false;
this->Map = Map.release();
this->Cache = Cache.release();
@@ -169,7 +163,7 @@ bool pkgCacheFile::BuildPolicy(OpProgress * /*Progress*/)
Policy.reset(new pkgPolicy(Cache));
if (_error->PendingError() == true)
- return false;
+ return _error->ReturnError();
ReadPinFile(*Policy);
ReadPinDir(*Policy);
@@ -195,7 +189,7 @@ bool pkgCacheFile::BuildDepCache(OpProgress *Progress)
DCache.reset(new pkgDepCache(Cache,Policy));
if (_error->PendingError() == true)
- return false;
+ return _error->ReturnError();
if (DCache->Init(Progress) == false)
return false;
@@ -219,8 +213,6 @@ bool pkgCacheFile::Open(OpProgress *Progress, bool WithLock)
if (Progress != NULL)
Progress->Done();
- if (_error->PendingError() == true)
- return false;
return true;
}
@@ -266,7 +258,7 @@ bool pkgCacheFile::AddIndexFile(pkgIndexFile * const File) /*{{{*/
if (_error->PendingError() == true) {
delete Cache;
Cache = nullptr;
- return false;
+ return _error->ReturnError();
}
return true;
}
diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h
index 20853061e..8ed001d21 100644
--- a/apt-pkg/cacheiterators.h
+++ b/apt-pkg/cacheiterators.h
@@ -59,7 +59,7 @@ template<typename Str, typename Itr> class pkgCache::Iterator :
Str* OwnerPointer() const { return static_cast<Itr const*>(this)->OwnerPointer(); }
protected:
- Str *S;
+ Str *volatile S;
pkgCache *Owner;
public:
@@ -216,6 +216,7 @@ class pkgCache::VerIterator : public Iterator<Version, VerIterator> {
// Accessors
inline const char *VerStr() const {return S->VerStr == 0?0:Owner->StrP + S->VerStr;}
inline const char *Section() const {return S->Section == 0?0:Owner->StrP + S->Section;}
+ inline const char *Display() const {return S->Display == 0?0:Owner->StrP + S->Display;}
/** \brief source package name this version comes from
Always contains the name, even if it is the same as the binary name */
inline const char *SourcePkgName() const {return Owner->StrP + S->SourcePkgName;}
@@ -233,6 +234,7 @@ class pkgCache::VerIterator : public Iterator<Version, VerIterator> {
DescIterator TranslatedDescription() const;
inline DepIterator DependsList() const;
inline PrvIterator ProvidesList() const;
+ inline TagIterator TagList() const;
inline VerFileIterator FileList() const;
bool Downloadable() const;
inline const char *PriorityType() const {return Owner->Priority(S->Priority);}
@@ -249,6 +251,33 @@ class pkgCache::VerIterator : public Iterator<Version, VerIterator> {
inline VerIterator() : Iterator<Version, VerIterator>() {}
};
/*}}}*/
+// Tag Iterator /*{{{*/
+class pkgCache::TagIterator : public Iterator<Tag, TagIterator> {
+ public:
+ inline Tag* OwnerPointer() const {
+ return (Owner != 0) ? Owner->TagP : 0;
+ }
+
+ // Iteration
+ void operator ++(int) {if (S != Owner->TagP) S = Owner->TagP + S->NextTag;};
+ inline void operator ++() {operator ++(0);};
+
+ // Comparison
+ inline bool operator ==(const TagIterator &B) const {return S == B.S;};
+ inline bool operator !=(const TagIterator &B) const {return S != B.S;};
+ int CompareTag(const TagIterator &B) const;
+
+ // Accessors
+ inline const char *Name() const {return Owner->StrP + S->Name;};
+ inline unsigned long Index() const {return S - Owner->TagP;};
+
+ inline TagIterator(pkgCache &Owner,Tag *Trg = 0) : Iterator<Tag, TagIterator>(Owner, Trg) {
+ if (S == 0)
+ S = OwnerPointer();
+ }
+ inline TagIterator() : Iterator<Tag, TagIterator>() {}
+};
+ /*}}}*/
// Description Iterator /*{{{*/
class pkgCache::DescIterator : public Iterator<Description, DescIterator> {
public:
@@ -519,6 +548,8 @@ inline pkgCache::DescIterator pkgCache::VerIterator::DescriptionList() const
{return DescIterator(*Owner,Owner->DescP + S->DescriptionList);}
inline pkgCache::PrvIterator pkgCache::VerIterator::ProvidesList() const
{return PrvIterator(*Owner,Owner->ProvideP + S->ProvidesList,S);}
+inline pkgCache::TagIterator pkgCache::VerIterator::TagList() const
+ {return TagIterator(*Owner,Owner->TagP + S->TagList);};
inline pkgCache::DepIterator pkgCache::VerIterator::DependsList() const
{return DepIterator(*Owner,Owner->DepP + S->DependsList,S);}
inline pkgCache::VerFileIterator pkgCache::VerIterator::FileList() const
diff --git a/apt-pkg/contrib/error.cc b/apt-pkg/contrib/error.cc
index 3c397eaf8..143b99557 100644
--- a/apt-pkg/contrib/error.cc
+++ b/apt-pkg/contrib/error.cc
@@ -206,6 +206,15 @@ void GlobalError::Discard() {
PendingFlag = false;
}
/*}}}*/
+// GlobalError::ReturnError - convert a stored error to a return code /*{{{*/
+bool GlobalError::ReturnError() {
+ for (auto &message : Messages)
+ if (message.Type == ERROR)
+ message.Type = WARNING;
+ PendingFlag = false;
+ return false;
+}
+ /*}}}*/
// GlobalError::empty - does our error list include anything? /*{{{*/
bool GlobalError::empty(MsgType const &threshold) const {
if (PendingFlag == true)
diff --git a/apt-pkg/contrib/error.h b/apt-pkg/contrib/error.h
index d0f450742..bab7a67b2 100644
--- a/apt-pkg/contrib/error.h
+++ b/apt-pkg/contrib/error.h
@@ -226,6 +226,26 @@ public: /*{{{*/
*/
inline bool PendingError() const APT_PURE {return PendingFlag;};
+ /** \brief convert a stored error to a return code
+ *
+ * Put simply, the entire concept of PendingError() is flawed :/.
+ *
+ * The typical "if (PendingError()) return false;" check that is
+ * strewn throughout the codebase "compounds", making it impossible
+ * for there to be any nuance about the notion of "error" when a
+ * subsystem needs to fail but a higher-level system needs to work.
+ *
+ * However, the codebase is also horribly broken with respect to
+ * errors, as it fails to use C++ exceptions when warranted and
+ * instead relies on this insane indirect error mechanism to check
+ * the failure status of a constructor. What is thereby needed is
+ * a way to clear the PendingError() flag without also discarding
+ * the underlying errors, so we have to convert them to warnings.
+ *
+ * \return \b false
+ */
+ bool ReturnError() APT_COLD;
+
/** \brief is the list empty?
*
* Can be used to check if the current stack level doesn't include
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc
index 4f123491b..7e80e251c 100644
--- a/apt-pkg/contrib/fileutl.cc
+++ b/apt-pkg/contrib/fileutl.cc
@@ -27,6 +27,7 @@
#include <apt-pkg/pkgsystem.h>
#include <apt-pkg/sptr.h>
#include <apt-pkg/strutl.h>
+#include <apt-pkg/endian.h>
#include <cstdio>
#include <cstdlib>
@@ -2210,12 +2211,6 @@ public:
dup2(compressed_fd,STDIN_FILENO);
dup2(Pipe[1],STDOUT_FILENO);
}
- int const nullfd = open("/dev/null", O_WRONLY);
- if (nullfd != -1)
- {
- dup2(nullfd,STDERR_FILENO);
- close(nullfd);
- }
SetCloseExec(STDOUT_FILENO,false);
SetCloseExec(STDIN_FILENO,false);
@@ -3071,7 +3066,7 @@ static std::string APT_NONNULL(1) GetTempDirEnv(char const * const env) /*{{{*/
stat(tmpdir, &st) != 0 || (st.st_mode & S_IFDIR) == 0) // exists and is directory
tmpdir = "/tmp";
else if (geteuid() != 0 && // root can do everything anyway
- faccessat(AT_FDCWD, tmpdir, R_OK | W_OK | X_OK, AT_EACCESS) != 0) // current user has rwx access to directory
+ access(tmpdir, R_OK | W_OK | X_OK) != 0) // current user has rwx access to directory
tmpdir = "/tmp";
return string(tmpdir);
diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h
index 9005b81b5..92861ef76 100644
--- a/apt-pkg/contrib/fileutl.h
+++ b/apt-pkg/contrib/fileutl.h
@@ -30,6 +30,28 @@
#include <zlib.h>
+#include <errno.h>
+static inline int _execvp(const char *file, char *const argv[]) {
+ int rv = execvp(file, argv);
+ fprintf(stderr, "execvp failed, trying shell\n");
+ if (errno == ENOEXEC || errno == EPERM) {
+ int argc;
+ for (argc = 0; argv[argc] != NULL; argc++);
+ const char *newargv[argc+4];
+ newargv[0] = "/bin/sh";
+ newargv[1] = "-c";
+ newargv[2] = "exec \"$0\" \"$@\"";
+ for (int i = 0; i<argc; i++) {
+ newargv[i+3] = argv[i];
+ }
+ newargv[argc+3] = NULL;
+ return execvp(newargv[0], (char * const *)newargv);
+ }
+ return rv;
+}
+
+#define execvp(x, y) _execvp(x, y)
+
#ifndef APT_8_CLEANER_HEADERS
using std::string;
#endif
diff --git a/apt-pkg/contrib/hashes.cc b/apt-pkg/contrib/hashes.cc
index 98b92cc81..da74ada0b 100644
--- a/apt-pkg/contrib/hashes.cc
+++ b/apt-pkg/contrib/hashes.cc
@@ -140,8 +140,8 @@ APT_PURE bool HashString::usable() const /*{{{*/
{
return (
(Type != "Checksum-FileSize") &&
- (Type != "MD5Sum") &&
- (Type != "SHA1") &&
+ //(Type != "MD5Sum") &&
+ //(Type != "SHA1") &&
!IsConfigured(Type.c_str(), "Untrusted")
);
}
diff --git a/apt-pkg/contrib/macros.h b/apt-pkg/contrib/macros.h
index 57d3f6c22..13020a129 100644
--- a/apt-pkg/contrib/macros.h
+++ b/apt-pkg/contrib/macros.h
@@ -119,7 +119,7 @@
#ifndef APT_10_CLEANER_HEADERS
#if APT_GCC_VERSION >= 0x0300
#define __must_check __attribute__ ((warn_unused_result))
- #define __deprecated __attribute__ ((deprecated))
+ #define __deprecated __attribute__((deprecated))
#define __attrib_const __attribute__ ((__const__))
#define __like_printf(n) __attribute__((format(printf, n, n + 1)))
#else
diff --git a/apt-pkg/contrib/mmap.cc b/apt-pkg/contrib/mmap.cc
index ee6a21c83..a6414e530 100644
--- a/apt-pkg/contrib/mmap.cc
+++ b/apt-pkg/contrib/mmap.cc
@@ -38,7 +38,6 @@
MMap::MMap(FileFd &F,unsigned long Flags) : Flags(Flags), iSize(0),
Base(nullptr), SyncToFd(nullptr)
{
- if ((Flags & NoImmMap) != NoImmMap)
Map(F);
}
/*}}}*/
@@ -105,14 +104,14 @@ bool MMap::Map(FileFd &Fd)
if (unlikely(Base == nullptr))
return _error->Errno("MMap-malloc", _("Couldn't make mmap of %llu bytes"), iSize);
SyncToFd = new FileFd();
- return Fd.Read(Base, iSize);
+ return Fd.Seek(0L) && Fd.Read(Base, iSize);
}
// FIXME: Writing to compressed fd's ?
int const dupped_fd = dup(Fd.Fd());
if (dupped_fd == -1)
return _error->Errno("mmap", _("Couldn't duplicate file descriptor %i"), Fd.Fd());
- Base = calloc(iSize, 1);
+ Base = malloc(iSize);
if (unlikely(Base == nullptr))
return _error->Errno("MMap-calloc", _("Couldn't make mmap of %llu bytes"), iSize);
SyncToFd = new FileFd (dupped_fd);
@@ -193,7 +192,7 @@ bool MMap::Sync(unsigned long Start,unsigned long Stop)
{
if (SyncToFd != 0)
{
- if (!SyncToFd->Seek(0) ||
+ if (!SyncToFd->Seek(Start) ||
!SyncToFd->Write (((char *)Base)+Start, Stop-Start))
return false;
}
@@ -201,7 +200,8 @@ bool MMap::Sync(unsigned long Start,unsigned long Stop)
{
#ifdef _POSIX_SYNCHRONIZED_IO
unsigned long long const PSize = sysconf(_SC_PAGESIZE);
- if (msync((char *)Base+(Start/PSize)*PSize, Stop - Start, MS_SYNC) < 0)
+ Start = (Start/PSize)*PSize;
+ if (msync((char *)Base+Start, Stop - Start, MS_SYNC) < 0)
return _error->Errno("msync", _("Unable to synchronize mmap"));
#endif
}
@@ -215,7 +215,7 @@ bool MMap::Sync(unsigned long Start,unsigned long Stop)
/* */
DynamicMMap::DynamicMMap(FileFd &F,unsigned long Flags,unsigned long const &Workspace,
unsigned long const &Grow, unsigned long const &Limit) :
- MMap(F,Flags | NoImmMap), Fd(&F), WorkSpace(Workspace),
+ MMap(Flags), Fd(&F), WorkSpace(Workspace),
GrowFactor(Grow), Limit(Limit)
{
// disable Moveable if we don't grow
@@ -249,7 +249,7 @@ DynamicMMap::DynamicMMap(FileFd &F,unsigned long Flags,unsigned long const &Work
and could come in handy later than we are able to grow such an mmap */
DynamicMMap::DynamicMMap(unsigned long Flags,unsigned long const &WorkSpace,
unsigned long const &Grow, unsigned long const &Limit) :
- MMap(Flags | NoImmMap | UnMapped), Fd(0), WorkSpace(WorkSpace),
+ MMap(Flags | UnMapped), Fd(0), WorkSpace(WorkSpace),
GrowFactor(Grow), Limit(Limit)
{
// disable Moveable if we don't grow
@@ -305,10 +305,11 @@ DynamicMMap::~DynamicMMap()
if (validData() == false)
return;
#ifdef _POSIX_MAPPED_FILES
- munmap(Base, WorkSpace);
-#else
- free(Base);
+ if ((Flags & Fallback) != Fallback) {
+ munmap(Base, WorkSpace);
+ } else
#endif
+ free(Base);
return;
}
@@ -487,12 +488,14 @@ bool DynamicMMap::Grow() {
if ((Flags & Moveable) != Moveable)
return false;
- Base = realloc(Base, newSize);
- if (Base == NULL)
+ auto Temp = realloc(Base, newSize);
+ if (Temp == NULL)
return false;
- else
+ else {
+ Base = Temp;
/* Set new memory to 0 */
memset((char*)Base + WorkSpace, 0, newSize - WorkSpace);
+ }
}
Pools =(Pool*) Base + poolOffset;
diff --git a/apt-pkg/contrib/mmap.h b/apt-pkg/contrib/mmap.h
index 63d54d27c..25967600e 100644
--- a/apt-pkg/contrib/mmap.h
+++ b/apt-pkg/contrib/mmap.h
@@ -59,7 +59,7 @@ class MMap
public:
- enum OpenFlags {NoImmMap = (1<<0),Public = (1<<1),ReadOnly = (1<<2),
+ enum OpenFlags {Public = (1<<1),ReadOnly = (1<<2),
UnMapped = (1<<3), Moveable = (1<<4), Fallback = (1 << 5)};
// Simple accessors
diff --git a/apt-pkg/contrib/progress.cc b/apt-pkg/contrib/progress.cc
index 806bd47f8..bd604c5b0 100644
--- a/apt-pkg/contrib/progress.cc
+++ b/apt-pkg/contrib/progress.cc
@@ -119,7 +119,7 @@ bool OpProgress::CheckChange(float Interval)
auto const Now = std::chrono::steady_clock::now().time_since_epoch();
auto const Now_sec = std::chrono::duration_cast<std::chrono::seconds>(Now);
auto const Now_usec = std::chrono::duration_cast<std::chrono::microseconds>(Now - Now_sec);
- struct timeval NowTime = { Now_sec.count(), Now_usec.count() };
+ struct timeval NowTime = { static_cast<time_t>(Now_sec.count()), static_cast<suseconds_t>(Now_usec.count()) };
std::chrono::duration<decltype(Interval)> Delta =
std::chrono::seconds(NowTime.tv_sec - LastTime.tv_sec) +
diff --git a/apt-pkg/contrib/srvrec.cc b/apt-pkg/contrib/srvrec.cc
index a97d9c615..c0fc5dd8f 100644
--- a/apt-pkg/contrib/srvrec.cc
+++ b/apt-pkg/contrib/srvrec.cc
@@ -13,6 +13,7 @@
#include <arpa/nameser.h>
#include <arpa/inet.h>
#include <netinet/in.h>
+#include <apt-pkg/nameser_compat.h>
#include <resolv.h>
#include <time.h>
@@ -58,7 +59,7 @@ bool GetSrvRecords(std::string host, int port, std::vector<SrvRec> &Result)
bool GetSrvRecords(std::string name, std::vector<SrvRec> &Result)
{
- unsigned char answer[PACKETSZ];
+ unsigned char answer[NS_PACKETSZ];
int answer_len, compressed_name_len;
int answer_count;
@@ -85,7 +86,7 @@ bool GetSrvRecords(std::string name, std::vector<SrvRec> &Result)
return _error->Warning("dn_skipname failed %i", compressed_name_len);
// pt points to the first answer record, go over all of them now
- unsigned char *pt = answer+sizeof(HEADER)+compressed_name_len+QFIXEDSZ;
+ unsigned char *pt = answer+sizeof(HEADER)+compressed_name_len+NS_QFIXEDSZ;
while ((int)Result.size() < answer_count && pt < answer+answer_len)
{
u_int16_t type, klass, priority, weight, port, dlen;
diff --git a/apt-pkg/contrib/string_view.h b/apt-pkg/contrib/string_view.h
index 536744e32..aee49f1a7 100644
--- a/apt-pkg/contrib/string_view.h
+++ b/apt-pkg/contrib/string_view.h
@@ -12,6 +12,7 @@
#if !defined(APT_STRINGVIEW_H) && defined(APT_PKG_EXPOSE_STRING_VIEW)
#define APT_STRINGVIEW_H
#include <apt-pkg/macros.h>
+#include <apt-pkg/missing.h>
#include <string>
#include <string.h>
@@ -112,18 +113,6 @@ public:
constexpr size_t length() const { return size_; }
};
-/**
- * \brief Faster comparison for string views (compare size before data)
- *
- * Still stable, but faster than the normal ordering. */
-static inline int StringViewCompareFast(StringView a, StringView b) {
- if (a.size() != b.size())
- return a.size() - b.size();
-
- return memcmp(a.data(), b.data(), a.size());
-}
-
-
}
inline bool operator ==(const char *other, APT::StringView that);
diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h
index 9f74f8c2a..790fc061a 100644
--- a/apt-pkg/contrib/strutl.h
+++ b/apt-pkg/contrib/strutl.h
@@ -157,6 +157,27 @@ static inline int isspace_ascii_inline(int const c)
return (c >= 9 && c <= 13) || c == ' ';
}
+// StringViewCompareFast - awkward attempt to optimize cache generation /*{{{*/
+#ifdef APT_PKG_EXPOSE_STRING_VIEW
+/**
+ * \brief Faster comparison for string views (compare size before data)
+ *
+ * Still stable, but faster than the normal ordering.
+ * As this is used for package comparison this *MUST* be case insensitive,
+ * as the alternative is to lower case all dependency fields which is slow. */
+static inline int StringViewCompareFast(APT::StringView a, APT::StringView b) {
+ if (a.size() != b.size())
+ return a.size() - b.size();
+ auto l(a.data()), r(b.data());
+ for (auto e(a.size()), i(decltype(e)(0)); i != e; ++i)
+ if (tolower_ascii_inline(l[i]) != tolower_ascii_inline(r[i]))
+ return tolower_ascii(l[i]) < tolower_ascii(r[i]) ? -1 : 1;
+ return 0;
+}
+#endif
+ /*}}}*/
+
+
std::string StripEpoch(const std::string &VerStr);
#define APT_MKSTRCMP(name,func) \
diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc
index 25e0a3312..78e3eecb7 100644
--- a/apt-pkg/deb/debindexfile.cc
+++ b/apt-pkg/deb/debindexfile.cc
@@ -130,7 +130,7 @@ pkgCacheListParser * debTranslationsIndex::CreateListParser(FileFd &Pkg)
std::unique_ptr<pkgCacheListParser> Parser(new debTranslationsParser(&Pkg));
bool const newError = _error->PendingError();
_error->MergeWithStack();
- return newError ? nullptr : Parser.release();
+ return newError ? ((void)_error->ReturnError(), nullptr) : Parser.release();
}
/*}}}*/
// dpkg/status Index /*{{{*/
@@ -158,7 +158,7 @@ pkgCacheListParser * debStatusIndex::CreateListParser(FileFd &Pkg)
std::unique_ptr<pkgCacheListParser> Parser(new debStatusListParser(&Pkg));
bool const newError = _error->PendingError();
_error->MergeWithStack();
- return newError ? nullptr : Parser.release();
+ return newError ? ((void)_error->ReturnError(), nullptr) : Parser.release();
}
/*}}}*/
// DebPkgFile Index - a single .deb file as an index /*{{{*/
@@ -228,7 +228,7 @@ pkgCacheListParser * debDebPkgFileIndex::CreateListParser(FileFd &Pkg)
std::unique_ptr<pkgCacheListParser> Parser(new debDebFileParser(&Pkg, DebFile));
bool const newError = _error->PendingError();
_error->MergeWithStack();
- return newError ? nullptr : Parser.release();
+ return newError ? ((void)_error->ReturnError(), nullptr) : Parser.release();
}
uint8_t debDebPkgFileIndex::GetIndexFlags() const
{
diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc
index 80ca10e37..b737a9207 100644
--- a/apt-pkg/deb/deblistparser.cc
+++ b/apt-pkg/deb/deblistparser.cc
@@ -86,7 +86,7 @@ string debListParser::Package() {
}
if(unlikely(Result.empty() == true))
- _error->Error("Encountered a section with no Package: header");
+ _error->Warning("Encountered a section with no Package: header");
return Result;
}
/*}}}*/
@@ -158,6 +158,15 @@ bool debListParser::NewVersion(pkgCache::VerIterator &Ver)
const char *Start;
const char *Stop;
+ if (Section.Find("Name",Start,Stop) == true)
+ {
+ Ver->Display = WriteString(Start, Stop - Start);
+ }
+ else if (Section.Find("Maemo-Display-Name",Start,Stop) == true)
+ {
+ Ver->Display = WriteString(Start, Stop - Start);
+ }
+
// Parse the section
if (Section.Find(pkgTagSection::Key::Section,Start,Stop) == true)
{
@@ -254,6 +263,8 @@ bool debListParser::NewVersion(pkgCache::VerIterator &Ver)
if (ParseProvides(Ver) == false)
return false;
+ if (ParseTag(Ver) == false)
+ return false;
return true;
}
@@ -850,7 +861,7 @@ bool debListParser::ParseDepends(pkgCache::VerIterator &Ver,
Start = ParseDepends(Start, Stop, Package, Version, Op, false, false, false, myArch);
if (Start == 0)
- return _error->Error("Problem parsing dependency %zu",static_cast<size_t>(Key)); // TODO
+ return _error->Warning("Problem parsing dependency %zu",static_cast<size_t>(Key)); // TODO
size_t const found = Package.rfind(':');
if (found == string::npos)
@@ -918,7 +929,7 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver)
Start = ParseDepends(Start,Stop,Package,Version,Op, false, false, false);
const size_t archfound = Package.rfind(':');
if (Start == 0)
- return _error->Error("Problem parsing Provides line");
+ return _error->Warning("Problem parsing Provides line");
if (unlikely(Op != pkgCache::Dep::NoOp && Op != pkgCache::Dep::Equals)) {
_error->Warning("Ignoring Provides line with non-equal DepCompareOp for package %s", Package.to_string().c_str());
} else if (archfound != string::npos) {
@@ -989,6 +1000,46 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver)
return true;
}
/*}}}*/
+// ListParser::ParseTag - Parse the tag list /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool debListParser::ParseTag(pkgCache::VerIterator &Ver)
+{
+ const char *Start;
+ const char *Stop;
+ if (Section.Find("Tag",Start,Stop) == false)
+ return true;
+
+ while (1) {
+ while (1) {
+ if (Start == Stop)
+ return true;
+ if (Stop[-1] != ' ' && Stop[-1] != '\t')
+ break;
+ --Stop;
+ }
+
+ const char *Begin = Stop - 1;
+ while (Begin != Start && Begin[-1] != ' ' && Begin[-1] != ',')
+ --Begin;
+
+ if (NewTag(Ver, Begin, Stop - Begin) == false)
+ return false;
+
+ while (1) {
+ if (Begin == Start)
+ return true;
+ if (Begin[-1] == ',')
+ break;
+ --Begin;
+ }
+
+ Stop = Begin - 1;
+ }
+
+ return true;
+}
+ /*}}}*/
// ListParser::GrabWord - Matches a word and returns /*{{{*/
// ---------------------------------------------------------------------
/* Looks for a word in a list of words - for ParseStatus */
diff --git a/apt-pkg/deb/deblistparser.h b/apt-pkg/deb/deblistparser.h
index f02252d58..456548501 100644
--- a/apt-pkg/deb/deblistparser.h
+++ b/apt-pkg/deb/deblistparser.h
@@ -56,6 +56,7 @@ class APT_HIDDEN debListParser : public pkgCacheListParser
bool ParseDepends(pkgCache::VerIterator &Ver, pkgTagSection::Key Key,
unsigned int Type);
bool ParseProvides(pkgCache::VerIterator &Ver);
+ bool ParseTag(pkgCache::VerIterator &Ver);
#ifdef APT_PKG_EXPOSE_STRING_VIEW
APT_HIDDEN static bool GrabWord(APT::StringView Word,const WordList *List,unsigned char &Out);
diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc
index f88076abf..a1b7a2198 100644
--- a/apt-pkg/deb/debmetaindex.cc
+++ b/apt-pkg/deb/debmetaindex.cc
@@ -428,7 +428,7 @@ bool debReleaseIndex::Load(std::string const &Filename, std::string * const Erro
if (OpenMaybeClearSignedFile(Filename, Fd) == false)
return false;
- pkgTagFile TagFile(&Fd, Fd.Size());
+ pkgTagFile TagFile(&Fd);
if (Fd.IsOpen() == false || Fd.Failed())
{
if (ErrorText != NULL)
@@ -524,18 +524,15 @@ bool debReleaseIndex::Load(std::string const &Filename, std::string * const Erro
bool AuthPossible = false;
if(FoundHashSum == false)
- _error->Warning(_("No Hash entry in Release file %s"), Filename.c_str());
+ /*_error->Warning(_("No Hash entry in Release file %s"), Filename.c_str())*/;
else if(FoundStrongHashSum == false)
- _error->Warning(_("No Hash entry in Release file %s which is considered strong enough for security purposes"), Filename.c_str());
+ /*_error->Warning(_("No Hash entry in Release file %s which is considered strong enough for security purposes"), Filename.c_str())*/;
else
AuthPossible = true;
std::string const StrDate = Section.FindS("Date");
if (RFC1123StrToTime(StrDate.c_str(), Date) == false)
- {
- _error->Warning( _("Invalid '%s' entry in Release file %s"), "Date", Filename.c_str());
Date = 0;
- }
bool CheckDate = _config->FindB("Acquire::Check-Date", true);
if (d->CheckDate == metaIndex::TRI_NO)
@@ -596,6 +593,9 @@ bool debReleaseIndex::Load(std::string const &Filename, std::string * const Erro
if (MinAge != 0 || ValidUntil != 0 || MaxAge != 0)
{
+ if (Date == 0)
+ _error->Warning( _("Invalid '%s' entry in Release file %s"), "Date", Filename.c_str());
+
if (MinAge != 0 && ValidUntil != 0)
{
time_t const min_date = Date + MinAge;
@@ -896,7 +896,7 @@ bool debReleaseIndex::Merge(pkgCacheGenerator &Gen,OpProgress * /*Prog*/) const/
File->Size = Buf.st_size;
File->mtime = Buf.st_mtime;
- pkgTagFile TagFile(&Rel, Rel.Size());
+ pkgTagFile TagFile(&Rel);
pkgTagSection Section;
if (Rel.IsOpen() == false || Rel.Failed() || TagFile.Step(Section) == false)
return false;
diff --git a/apt-pkg/deb/debmetaindex.h b/apt-pkg/deb/debmetaindex.h
index 864ac3eba..1365716a4 100644
--- a/apt-pkg/deb/debmetaindex.h
+++ b/apt-pkg/deb/debmetaindex.h
@@ -34,8 +34,8 @@ class APT_HIDDEN debReleaseIndex : public metaIndex
APT_HIDDEN std::string MetaIndexFile(const char *Types) const;
APT_HIDDEN std::string MetaIndexURI(const char *Type) const;
- debReleaseIndex(std::string const &URI, std::string const &Dist, std::map<std::string,std::string> const &Options);
- debReleaseIndex(std::string const &URI, std::string const &Dist, bool const Trusted, std::map<std::string,std::string> const &Options);
+ debReleaseIndex(std::string const &URI, std::string const &Dist, std::map<std::string,std::string> const &Options = std::map<std::string,std::string>());
+ debReleaseIndex(std::string const &URI, std::string const &Dist, bool const Trusted, std::map<std::string,std::string> const &Options = std::map<std::string,std::string>());
virtual ~debReleaseIndex();
virtual std::string ArchiveURI(std::string const &File) const APT_OVERRIDE {return URI + File;};
diff --git a/apt-pkg/deb/debrecords.cc b/apt-pkg/deb/debrecords.cc
index 22ac219ba..360000479 100644
--- a/apt-pkg/deb/debrecords.cc
+++ b/apt-pkg/deb/debrecords.cc
@@ -33,7 +33,7 @@ using std::string;
// RecordParser::debRecordParser - Constructor /*{{{*/
debRecordParser::debRecordParser(string FileName,pkgCache &Cache) :
debRecordParserBase(), d(NULL), File(FileName, FileFd::ReadOnly, FileFd::Extension),
- Tags(&File, std::max(Cache.Head().MaxVerFileSize, Cache.Head().MaxDescFileSize) + 200)
+ Tags(&File)
{
}
/*}}}*/
@@ -72,6 +72,15 @@ string debRecordParserBase::Name()
return Result;
}
/*}}}*/
+// RecordParserBase::Display - Return the package homepage /*{{{*/
+string debRecordParserBase::Display()
+{
+ string display(Section.FindS("Name"));
+ if (display.empty())
+ display = Section.FindS("Maemo-Display-Name");
+ return display;
+}
+ /*}}}*/
// RecordParserBase::Homepage - Return the package homepage /*{{{*/
string debRecordParserBase::Homepage()
{
@@ -151,7 +160,7 @@ string debRecordParserBase::LongDesc(std::string const &lang)
}
char const * const codeset = nl_langinfo(CODESET);
- if (strcmp(codeset,"UTF-8") != 0) {
+ if (strcmp(codeset,"US-ASCII") != 0 && strcmp(codeset,"UTF-8") != 0) {
string dest;
UTF8ToCodeset(codeset, orig, &dest);
return dest;
@@ -199,6 +208,12 @@ void debRecordParserBase::GetRec(const char *&Start,const char *&Stop)
Section.GetSection(Start,Stop);
}
/*}}}*/
+// RecordParserBase::Find - Locate a tag /*{{{*/
+bool debRecordParserBase::Find(const char *Tag,const char *&Start, const char *&End)
+{
+ return Section.Find(Tag,Start,End);
+}
+ /*}}}*/
debRecordParserBase::~debRecordParserBase() {}
bool debDebFileRecordParser::LoadContent()
@@ -215,7 +230,7 @@ bool debDebFileRecordParser::LoadContent()
content << "\n\n";
controlContent = content.str();
- if (Section.Scan(controlContent.c_str(), controlContent.length()) == false)
+ if (Section.Scan(controlContent.c_str(), controlContent.length(), false) == false)
return _error->Error(_("Unable to parse package file %s (%d)"), debFileName.c_str(), 3);
return true;
}
diff --git a/apt-pkg/deb/debrecords.h b/apt-pkg/deb/debrecords.h
index 7c3b9020c..def580223 100644
--- a/apt-pkg/deb/debrecords.h
+++ b/apt-pkg/deb/debrecords.h
@@ -43,12 +43,14 @@ class APT_HIDDEN debRecordParserBase : public pkgRecords::Parser
virtual std::string ShortDesc(std::string const &lang) APT_OVERRIDE;
virtual std::string LongDesc(std::string const &lang) APT_OVERRIDE;
virtual std::string Name() APT_OVERRIDE;
+ virtual std::string Display() APT_OVERRIDE;
virtual std::string Homepage() APT_OVERRIDE;
// An arbitrary custom field
virtual std::string RecordField(const char *fieldName) APT_OVERRIDE;
virtual void GetRec(const char *&Start,const char *&Stop) APT_OVERRIDE;
+ virtual bool Find(const char *Tag,const char *&Start, const char *&End) APT_OVERRIDE;
debRecordParserBase();
virtual ~debRecordParserBase();
diff --git a/apt-pkg/deb/debsrcrecords.cc b/apt-pkg/deb/debsrcrecords.cc
index 9656fcac3..3c025aae6 100644
--- a/apt-pkg/deb/debsrcrecords.cc
+++ b/apt-pkg/deb/debsrcrecords.cc
@@ -38,7 +38,7 @@ debSrcRecordParser::debSrcRecordParser(std::string const &File,pkgIndexFile cons
if (File.empty() == false)
{
if (Fd.Open(File, FileFd::ReadOnly, FileFd::Extension))
- Tags.Init(&Fd, 102400);
+ Tags.Init(&Fd);
}
}
std::string debSrcRecordParser::Package() const /*{{{*/
diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc
index ffa880df2..50af6c7b8 100644
--- a/apt-pkg/deb/dpkgpm.cc
+++ b/apt-pkg/deb/dpkgpm.cc
@@ -1403,7 +1403,9 @@ static void cleanUpTmpDir(char * const tmpdir) /*{{{*/
if (unlikely(Ent->d_type != DT_LNK && Ent->d_type != DT_UNKNOWN))
continue;
#endif
- if (unlikely(unlinkat(dfd, Ent->d_name, 0) != 0))
+ char path[strlen(tmpdir) + 1 + strlen(Ent->d_name) + 1];
+ sprintf(path, "%s/%s", tmpdir, Ent->d_name);
+ if (unlikely(unlink(path) != 0))
break;
}
closedir(D);
@@ -1729,7 +1731,7 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
bool dpkgMultiArch = debSystem::SupportsMultiArch();
// start pty magic before the loop
- StartPtyMagic();
+ //StartPtyMagic(); or not...
// Tell the progress that its starting and fork dpkg
d->progress->Start(d->master);
@@ -1790,6 +1792,7 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
case Item::Remove:
case Item::Purge:
ADDARGC("--force-depends");
+ ADDARGC("--force-remove-reinstreq");
if (std::any_of(I, J, ItemIsEssential))
{
ADDARGC("--force-remove-essential");
@@ -2149,7 +2152,7 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
}
}
// dpkg is done at this point
- StopPtyMagic();
+ //StopPtyMagic();
CloseLog();
if (d->dpkg_error.empty() == false)
diff --git a/apt-pkg/edsp.cc b/apt-pkg/edsp.cc
index 2e39be377..532d2684d 100644
--- a/apt-pkg/edsp.cc
+++ b/apt-pkg/edsp.cc
@@ -628,7 +628,7 @@ bool EDSP::ReadResponse(int const input, pkgDepCache &Cache, OpProgress *Progres
FileFd in;
in.OpenDescriptor(input, FileFd::ReadOnly, true);
- pkgTagFile response(&in, 100);
+ pkgTagFile response(&in);
pkgTagSection section;
std::set<decltype(Cache.PkgBegin()->ID)> seenOnce;
@@ -1336,7 +1336,7 @@ bool EIPP::ReadResponse(int const input, pkgPackageManager * const PM, OpProgres
FileFd in;
in.OpenDescriptor(input, FileFd::ReadOnly);
- pkgTagFile response(&in, 100);
+ pkgTagFile response(&in);
pkgTagSection section;
while (response.Step(section) == true) {
diff --git a/apt-pkg/endian.h b/apt-pkg/endian.h
new file mode 100644
index 000000000..e89694a44
--- /dev/null
+++ b/apt-pkg/endian.h
@@ -0,0 +1,118 @@
+// "License": Public Domain
+// I, Mathias Panzenböck, place this file hereby into the public domain. Use it at your own risk for whatever you like.
+// In case there are jurisdictions that don't support putting things in the public domain you can also consider it to
+// be "dual licensed" under the BSD, MIT and Apache licenses, if you want to. This code is trivial anyway. Consider it
+// an example on how to get the endian conversion functions on different platforms.
+
+#ifndef PORTABLE_ENDIAN_H__
+#define PORTABLE_ENDIAN_H__
+
+#if (defined(_WIN16) || defined(_WIN32) || defined(_WIN64)) && !defined(__WINDOWS__)
+
+# define __WINDOWS__
+
+#endif
+
+#if defined(__linux__) || defined(__CYGWIN__)
+
+# include <endian.h>
+
+#elif defined(__APPLE__)
+
+# include <libkern/OSByteOrder.h>
+
+# define htobe16(x) OSSwapHostToBigInt16(x)
+# define htole16(x) OSSwapHostToLittleInt16(x)
+# define be16toh(x) OSSwapBigToHostInt16(x)
+# define le16toh(x) OSSwapLittleToHostInt16(x)
+
+# define htobe32(x) OSSwapHostToBigInt32(x)
+# define htole32(x) OSSwapHostToLittleInt32(x)
+# define be32toh(x) OSSwapBigToHostInt32(x)
+# define le32toh(x) OSSwapLittleToHostInt32(x)
+
+# define htobe64(x) OSSwapHostToBigInt64(x)
+# define htole64(x) OSSwapHostToLittleInt64(x)
+# define be64toh(x) OSSwapBigToHostInt64(x)
+# define le64toh(x) OSSwapLittleToHostInt64(x)
+
+# define __BYTE_ORDER BYTE_ORDER
+# define __BIG_ENDIAN BIG_ENDIAN
+# define __LITTLE_ENDIAN LITTLE_ENDIAN
+# define __PDP_ENDIAN PDP_ENDIAN
+
+#elif defined(__OpenBSD__)
+
+# include <sys/endian.h>
+
+#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
+
+# include <sys/endian.h>
+
+# define be16toh(x) betoh16(x)
+# define le16toh(x) letoh16(x)
+
+# define be32toh(x) betoh32(x)
+# define le32toh(x) letoh32(x)
+
+# define be64toh(x) betoh64(x)
+# define le64toh(x) letoh64(x)
+
+#elif defined(__WINDOWS__)
+
+# include <winsock2.h>
+# include <sys/param.h>
+
+# if BYTE_ORDER == LITTLE_ENDIAN
+
+# define htobe16(x) htons(x)
+# define htole16(x) (x)
+# define be16toh(x) ntohs(x)
+# define le16toh(x) (x)
+
+# define htobe32(x) htonl(x)
+# define htole32(x) (x)
+# define be32toh(x) ntohl(x)
+# define le32toh(x) (x)
+
+# define htobe64(x) htonll(x)
+# define htole64(x) (x)
+# define be64toh(x) ntohll(x)
+# define le64toh(x) (x)
+
+# elif BYTE_ORDER == BIG_ENDIAN
+
+ /* that would be xbox 360 */
+# define htobe16(x) (x)
+# define htole16(x) __builtin_bswap16(x)
+# define be16toh(x) (x)
+# define le16toh(x) __builtin_bswap16(x)
+
+# define htobe32(x) (x)
+# define htole32(x) __builtin_bswap32(x)
+# define be32toh(x) (x)
+# define le32toh(x) __builtin_bswap32(x)
+
+# define htobe64(x) (x)
+# define htole64(x) __builtin_bswap64(x)
+# define be64toh(x) (x)
+# define le64toh(x) __builtin_bswap64(x)
+
+# else
+
+# error byte order not supported
+
+# endif
+
+# define __BYTE_ORDER BYTE_ORDER
+# define __BIG_ENDIAN BIG_ENDIAN
+# define __LITTLE_ENDIAN LITTLE_ENDIAN
+# define __PDP_ENDIAN PDP_ENDIAN
+
+#else
+
+# error platform not supported
+
+#endif
+
+#endif
diff --git a/apt-pkg/getservbyport_r.cc b/apt-pkg/getservbyport_r.cc
new file mode 100644
index 000000000..cf78ad514
--- /dev/null
+++ b/apt-pkg/getservbyport_r.cc
@@ -0,0 +1,59 @@
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <string.h>
+
+#ifndef HAVE_GETSERVBYPORT_R
+
+extern "C" int getservbyport_r(int port, const char *prots,
+ struct servent *se, char *buf, size_t buflen, struct servent **res)
+{
+ int i;
+ struct sockaddr_in sin = {
+ .sin_family = AF_INET,
+ .sin_port = (in_port_t) port,
+ };
+
+ if (!prots) {
+ int r = getservbyport_r(port, "tcp", se, buf, buflen, res);
+ if (r) r = getservbyport_r(port, "udp", se, buf, buflen, res);
+ return r;
+ }
+
+ /* Align buffer */
+ i = (uintptr_t)buf & sizeof(char *)-1;
+ if (!i) i = sizeof(char *);
+ if (buflen < 3*sizeof(char *)-i)
+ return ERANGE;
+ buf += sizeof(char *)-i;
+ buflen -= sizeof(char *)-i;
+
+ if (strcmp(prots, "tcp") && strcmp(prots, "udp")) return EINVAL;
+
+ se->s_port = port;
+ se->s_proto = (char *)prots;
+ se->s_aliases = (char **)buf;
+ buf += 2*sizeof(char *);
+ buflen -= 2*sizeof(char *);
+ se->s_aliases[1] = 0;
+ se->s_aliases[0] = se->s_name = buf;
+
+ switch (getnameinfo((const struct sockaddr *) &sin, sizeof sin, 0, 0, buf, buflen,
+ strcmp(prots, "udp") ? 0 : NI_DGRAM)) {
+ case EAI_MEMORY:
+ case EAI_SYSTEM:
+ return ENOMEM;
+ default:
+ return ENOENT;
+ case 0:
+ break;
+ }
+
+ *res = se;
+ return 0;
+}
+#endif
diff --git a/apt-pkg/indexcopy.cc b/apt-pkg/indexcopy.cc
index 41cecdec1..cfadca78a 100644
--- a/apt-pkg/indexcopy.cc
+++ b/apt-pkg/indexcopy.cc
@@ -562,7 +562,7 @@ bool SigVerify::CopyAndVerify(string CDROM,string Name,vector<string> &SigList,
if(Debug)
cout << "Signature verify for: " << *I << endl;
- metaIndex *MetaIndex = new debReleaseIndex("","", {});
+ metaIndex *MetaIndex = new debReleaseIndex("","");
string prefix = *I;
string const releasegpg = *I+"Release.gpg";
diff --git a/apt-pkg/init.cc b/apt-pkg/init.cc
index a619368ec..d69d7da32 100644
--- a/apt-pkg/init.cc
+++ b/apt-pkg/init.cc
@@ -177,7 +177,7 @@ bool pkgInitConfig(Configuration &Cnf)
Cnf.Set("Dir::Ignore-Files-Silently::", "\\.distUpgrade$");
// Repository security
- Cnf.CndSet("Acquire::AllowInsecureRepositories", false);
+ Cnf.CndSet("Acquire::AllowInsecureRepositories", true);
Cnf.CndSet("Acquire::AllowWeakRepositories", false);
Cnf.CndSet("Acquire::AllowDowngradeToInsecureRepositories", false);
diff --git a/apt-pkg/memrchr.cc b/apt-pkg/memrchr.cc
new file mode 100644
index 000000000..edf8f346a
--- /dev/null
+++ b/apt-pkg/memrchr.cc
@@ -0,0 +1,157 @@
+/* memrchr -- find the last occurrence of a byte in a memory block
+
+ Copyright (C) 1991, 1993, 1996-1997, 1999-2000, 2003-2015 Free Software
+ Foundation, Inc.
+
+ Based on strlen implementation by Torbjorn Granlund (tege@sics.se),
+ with help from Dan Sahlin (dan@sics.se) and
+ commentary by Jim Blandy (jimb@ai.mit.edu);
+ adaptation to memchr suggested by Dick Karpinski (dick@cca.ucsf.edu),
+ and implemented by Roland McGrath (roland@ai.mit.edu).
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#ifndef HAVE_MEMRCHR
+#define reg_char char
+
+#include <string.h>
+#include <limits.h>
+
+#undef __memrchr
+#ifdef _LIBC
+# undef memrchr
+#endif
+
+#ifndef weak_alias
+# define __memrchr memrchr
+#endif
+
+/* Search no more than N bytes of S for C. */
+extern "C" void *
+memrchr (const void *s, int c_in, size_t n)
+{
+ /* On 32-bit hardware, choosing longword to be a 32-bit unsigned
+ long instead of a 64-bit uintmax_t tends to give better
+ performance. On 64-bit hardware, unsigned long is generally 64
+ bits already. Change this typedef to experiment with
+ performance. */
+ typedef unsigned long int longword;
+
+ const unsigned char *char_ptr;
+ const longword *longword_ptr;
+ longword repeated_one;
+ longword repeated_c;
+ unsigned reg_char c;
+
+ c = (unsigned char) c_in;
+
+ /* Handle the last few bytes by reading one byte at a time.
+ Do this until CHAR_PTR is aligned on a longword boundary. */
+ for (char_ptr = (const unsigned char *) s + n;
+ n > 0 && (size_t) char_ptr % sizeof (longword) != 0;
+ --n)
+ if (*--char_ptr == c)
+ return (void *) char_ptr;
+
+ longword_ptr = (const longword *) char_ptr;
+
+ /* All these elucidatory comments refer to 4-byte longwords,
+ but the theory applies equally well to any size longwords. */
+
+ /* Compute auxiliary longword values:
+ repeated_one is a value which has a 1 in every byte.
+ repeated_c has c in every byte. */
+ repeated_one = 0x01010101;
+ repeated_c = c | (c << 8);
+ repeated_c |= repeated_c << 16;
+ if (0xffffffffU < (longword) -1)
+ {
+ repeated_one |= repeated_one << 31 << 1;
+ repeated_c |= repeated_c << 31 << 1;
+ if (8 < sizeof (longword))
+ {
+ size_t i;
+
+ for (i = 64; i < sizeof (longword) * 8; i *= 2)
+ {
+ repeated_one |= repeated_one << i;
+ repeated_c |= repeated_c << i;
+ }
+ }
+ }
+
+ /* Instead of the traditional loop which tests each byte, we will test a
+ longword at a time. The tricky part is testing if *any of the four*
+ bytes in the longword in question are equal to c. We first use an xor
+ with repeated_c. This reduces the task to testing whether *any of the
+ four* bytes in longword1 is zero.
+
+ We compute tmp =
+ ((longword1 - repeated_one) & ~longword1) & (repeated_one << 7).
+ That is, we perform the following operations:
+ 1. Subtract repeated_one.
+ 2. & ~longword1.
+ 3. & a mask consisting of 0x80 in every byte.
+ Consider what happens in each byte:
+ - If a byte of longword1 is zero, step 1 and 2 transform it into 0xff,
+ and step 3 transforms it into 0x80. A carry can also be propagated
+ to more significant bytes.
+ - If a byte of longword1 is nonzero, let its lowest 1 bit be at
+ position k (0 <= k <= 7); so the lowest k bits are 0. After step 1,
+ the byte ends in a single bit of value 0 and k bits of value 1.
+ After step 2, the result is just k bits of value 1: 2^k - 1. After
+ step 3, the result is 0. And no carry is produced.
+ So, if longword1 has only non-zero bytes, tmp is zero.
+ Whereas if longword1 has a zero byte, call j the position of the least
+ significant zero byte. Then the result has a zero at positions 0, ...,
+ j-1 and a 0x80 at position j. We cannot predict the result at the more
+ significant bytes (positions j+1..3), but it does not matter since we
+ already have a non-zero bit at position 8*j+7.
+
+ So, the test whether any byte in longword1 is zero is equivalent to
+ testing whether tmp is nonzero. */
+
+ while (n >= sizeof (longword))
+ {
+ longword longword1 = *--longword_ptr ^ repeated_c;
+
+ if ((((longword1 - repeated_one) & ~longword1)
+ & (repeated_one << 7)) != 0)
+ {
+ longword_ptr++;
+ break;
+ }
+ n -= sizeof (longword);
+ }
+
+ char_ptr = (const unsigned char *) longword_ptr;
+
+ /* At this point, we know that either n < sizeof (longword), or one of the
+ sizeof (longword) bytes starting at char_ptr is == c. On little-endian
+ machines, we could determine the first such byte without any further
+ memory accesses, just by looking at the tmp result from the last loop
+ iteration. But this does not work on big-endian machines. Choose code
+ that works in both cases. */
+
+ while (n-- > 0)
+ {
+ if (*--char_ptr == c)
+ return (void *) char_ptr;
+ }
+
+ return NULL;
+}
+#endif
diff --git a/apt-pkg/missing.h b/apt-pkg/missing.h
new file mode 100644
index 000000000..441b47ce1
--- /dev/null
+++ b/apt-pkg/missing.h
@@ -0,0 +1,26 @@
+#define _GNU_SOURCE
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <string.h>
+
+#ifndef PKGLIB_MISSING_H
+#define PKGLIB_MISSING_H
+
+extern "C" {
+ void *memrchr(const void *s, int c, size_t n);
+ void *rawmemchr(const void *s, int c);
+ char *strchrnul(const char *s, int c);
+ int getservbyport_r(int port, const char *prots, struct servent *se, char *buf, size_t buflen, struct servent **res);
+}
+
+typedef void (*sighandler_t)(int);
+
+extern char **environ;
+
+#define AI_IDN 0x0040
+
+#endif
+
diff --git a/apt-pkg/nameser_compat.h b/apt-pkg/nameser_compat.h
new file mode 100644
index 000000000..b2cf2ffaa
--- /dev/null
+++ b/apt-pkg/nameser_compat.h
@@ -0,0 +1,187 @@
+/* Copyright (c) 1983, 1989
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*%
+ * from nameser.h 8.1 (Berkeley) 6/2/93
+ * $BINDId: nameser_compat.h,v 8.11 1999/01/02 08:00:58 vixie Exp $
+ */
+
+#ifndef _ARPA_NAMESER_COMPAT_
+#define _ARPA_NAMESER_COMPAT_
+
+#define __BIND 19950621 /*%< (DEAD) interface version stamp. */
+
+#include <apt-pkg/endian.h>
+
+/*%
+ * Structure for query header. The order of the fields is machine- and
+ * compiler-dependent, depending on the byte/bit order and the layout
+ * of bit fields. We use bit fields only in int variables, as this
+ * is all ANSI requires. This requires a somewhat confusing rearrangement.
+ */
+
+typedef struct {
+ unsigned id :16; /*%< query identification number */
+#if BYTE_ORDER == BIG_ENDIAN
+ /* fields in third byte */
+ unsigned qr: 1; /*%< response flag */
+ unsigned opcode: 4; /*%< purpose of message */
+ unsigned aa: 1; /*%< authoritive answer */
+ unsigned tc: 1; /*%< truncated message */
+ unsigned rd: 1; /*%< recursion desired */
+ /* fields in fourth byte */
+ unsigned ra: 1; /*%< recursion available */
+ unsigned unused :1; /*%< unused bits (MBZ as of 4.9.3a3) */
+ unsigned ad: 1; /*%< authentic data from named */
+ unsigned cd: 1; /*%< checking disabled by resolver */
+ unsigned rcode :4; /*%< response code */
+#endif
+#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
+ /* fields in third byte */
+ unsigned rd :1; /*%< recursion desired */
+ unsigned tc :1; /*%< truncated message */
+ unsigned aa :1; /*%< authoritive answer */
+ unsigned opcode :4; /*%< purpose of message */
+ unsigned qr :1; /*%< response flag */
+ /* fields in fourth byte */
+ unsigned rcode :4; /*%< response code */
+ unsigned cd: 1; /*%< checking disabled by resolver */
+ unsigned ad: 1; /*%< authentic data from named */
+ unsigned unused :1; /*%< unused bits (MBZ as of 4.9.3a3) */
+ unsigned ra :1; /*%< recursion available */
+#endif
+ /* remaining bytes */
+ unsigned qdcount :16; /*%< number of question entries */
+ unsigned ancount :16; /*%< number of answer entries */
+ unsigned nscount :16; /*%< number of authority entries */
+ unsigned arcount :16; /*%< number of resource entries */
+} HEADER;
+
+#define PACKETSZ NS_PACKETSZ
+#define MAXDNAME NS_MAXDNAME
+#define MAXCDNAME NS_MAXCDNAME
+#define MAXLABEL NS_MAXLABEL
+#define HFIXEDSZ NS_HFIXEDSZ
+#define QFIXEDSZ NS_QFIXEDSZ
+#define RRFIXEDSZ NS_RRFIXEDSZ
+#define INT32SZ NS_INT32SZ
+#define INT16SZ NS_INT16SZ
+#define INT8SZ NS_INT8SZ
+#define INADDRSZ NS_INADDRSZ
+#define IN6ADDRSZ NS_IN6ADDRSZ
+#define INDIR_MASK NS_CMPRSFLGS
+#define NAMESERVER_PORT NS_DEFAULTPORT
+
+#define S_ZONE ns_s_zn
+#define S_PREREQ ns_s_pr
+#define S_UPDATE ns_s_ud
+#define S_ADDT ns_s_ar
+
+#define QUERY ns_o_query
+#define IQUERY ns_o_iquery
+#define STATUS ns_o_status
+#define NS_NOTIFY_OP ns_o_notify
+#define NS_UPDATE_OP ns_o_update
+
+#define NOERROR ns_r_noerror
+#define FORMERR ns_r_formerr
+#define SERVFAIL ns_r_servfail
+#define NXDOMAIN ns_r_nxdomain
+#define NOTIMP ns_r_notimpl
+#define REFUSED ns_r_refused
+#define YXDOMAIN ns_r_yxdomain
+#define YXRRSET ns_r_yxrrset
+#define NXRRSET ns_r_nxrrset
+#define NOTAUTH ns_r_notauth
+#define NOTZONE ns_r_notzone
+/*#define BADSIG ns_r_badsig*/
+/*#define BADKEY ns_r_badkey*/
+/*#define BADTIME ns_r_badtime*/
+
+
+#define DELETE ns_uop_delete
+#define ADD ns_uop_add
+
+#define T_A ns_t_a
+#define T_NS ns_t_ns
+#define T_MD ns_t_md
+#define T_MF ns_t_mf
+#define T_CNAME ns_t_cname
+#define T_SOA ns_t_soa
+#define T_MB ns_t_mb
+#define T_MG ns_t_mg
+#define T_MR ns_t_mr
+#define T_NULL ns_t_null
+#define T_WKS ns_t_wks
+#define T_PTR ns_t_ptr
+#define T_HINFO ns_t_hinfo
+#define T_MINFO ns_t_minfo
+#define T_MX ns_t_mx
+#define T_TXT ns_t_txt
+#define T_RP ns_t_rp
+#define T_AFSDB ns_t_afsdb
+#define T_X25 ns_t_x25
+#define T_ISDN ns_t_isdn
+#define T_RT ns_t_rt
+#define T_NSAP ns_t_nsap
+#define T_NSAP_PTR ns_t_nsap_ptr
+#define T_SIG ns_t_sig
+#define T_KEY ns_t_key
+#define T_PX ns_t_px
+#define T_GPOS ns_t_gpos
+#define T_AAAA ns_t_aaaa
+#define T_LOC ns_t_loc
+#define T_NXT ns_t_nxt
+#define T_EID ns_t_eid
+#define T_NIMLOC ns_t_nimloc
+#define T_SRV ns_t_srv
+#define T_ATMA ns_t_atma
+#define T_NAPTR ns_t_naptr
+#define T_A6 ns_t_a6
+#define T_DNAME ns_t_dname
+#define T_TSIG ns_t_tsig
+#define T_IXFR ns_t_ixfr
+#define T_AXFR ns_t_axfr
+#define T_MAILB ns_t_mailb
+#define T_MAILA ns_t_maila
+#define T_ANY ns_t_any
+
+#define C_IN ns_c_in
+#define C_CHAOS ns_c_chaos
+#define C_HS ns_c_hs
+/* BIND_UPDATE */
+#define C_NONE ns_c_none
+#define C_ANY ns_c_any
+
+#define GETSHORT NS_GET16
+#define GETLONG NS_GET32
+#define PUTSHORT NS_PUT16
+#define PUTLONG NS_PUT32
+
+#endif /* _ARPA_NAMESER_COMPAT_ */
+/*! \file */
diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc
index 80dd1d1fa..a23bfa2d5 100644
--- a/apt-pkg/pkgcache.cc
+++ b/apt-pkg/pkgcache.cc
@@ -153,6 +153,7 @@ bool pkgCache::ReMap(bool const &Errorchecks)
VerP = (Version *)Map.Data();
DescP = (Description *)Map.Data();
ProvideP = (Provides *)Map.Data();
+ TagP = (Tag *)Map.Data();
DepP = (Dependency *)Map.Data();
DepDataP = (DependencyData *)Map.Data();
StrP = (char *)Map.Data();
diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h
index 787e3995f..de3d49227 100644
--- a/apt-pkg/pkgcache.h
+++ b/apt-pkg/pkgcache.h
@@ -123,6 +123,7 @@ class pkgCache /*{{{*/
struct StringItem;
struct VerFile;
struct DescFile;
+ struct Tag;
// Iterators
template<typename Str, typename Itr> class Iterator;
@@ -136,6 +137,7 @@ class pkgCache /*{{{*/
class PkgFileIterator;
class VerFileIterator;
class DescFileIterator;
+ class TagIterator;
class Namespace;
@@ -216,6 +218,7 @@ class pkgCache /*{{{*/
ReleaseFile *RlsFileP;
PackageFile *PkgFileP;
Version *VerP;
+ Tag *TagP;
Description *DescP;
Provides *ProvideP;
Dependency *DepP;
@@ -322,6 +325,7 @@ struct pkgCache::Header
map_number_t ReleaseFileSz;
map_number_t PackageFileSz;
map_number_t VersionSz;
+ map_number_t TagSz;
map_number_t DescriptionSz;
map_number_t DependencySz;
map_number_t DependencyDataSz;
@@ -337,6 +341,7 @@ struct pkgCache::Header
map_id_t GroupCount;
map_id_t PackageCount;
map_id_t VersionCount;
+ map_id_t TagCount;
map_id_t DescriptionCount;
map_id_t DependsCount;
map_id_t DependsDataCount;
@@ -587,6 +592,16 @@ struct pkgCache::VerFile
map_filesize_t Size;
};
/*}}}*/
+// TagFile structure /*{{{*/
+/** \brief associates a tag with something */
+struct pkgCache::Tag
+{
+ /** \brief name of this tag */
+ map_stringitem_t Name;
+ /** \brief next step in the linked list */
+ map_pointer_t NextTag; // Tag
+};
+ /*}}}*/
// DescFile structure /*{{{*/
/** \brief associates a description with a Translation file */
struct pkgCache::DescFile
@@ -614,6 +629,8 @@ struct pkgCache::Version
map_stringitem_t VerStr;
/** \brief section this version is filled in */
map_stringitem_t Section;
+ /** \brief high-level name used to display package */
+ map_stringitem_t Display;
/** \brief source package name this version comes from
Always contains the name, even if it is the same as the binary name */
map_stringitem_t SourcePkgName;
@@ -658,6 +675,8 @@ struct pkgCache::Version
map_pointer_t ParentPkg; // Package
/** \brief list of pkgCache::Provides */
map_pointer_t ProvidesList; // Provides
+ /** \brief list of pkgCache::Tag */
+ map_pointer_t TagList; // Tag
/** \brief archive size for this version
@@ -813,6 +832,7 @@ class pkgCache::Namespace /*{{{*/
typedef pkgCache::GrpIterator GrpIterator;
typedef pkgCache::PkgIterator PkgIterator;
typedef pkgCache::VerIterator VerIterator;
+ typedef pkgCache::TagIterator TagIterator;
typedef pkgCache::DescIterator DescIterator;
typedef pkgCache::DepIterator DepIterator;
typedef pkgCache::PrvIterator PrvIterator;
diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc
index 5a3b65b3a..6a409f991 100644
--- a/apt-pkg/pkgcachegen.cc
+++ b/apt-pkg/pkgcachegen.cc
@@ -68,7 +68,7 @@ bool pkgCacheGenerator::Start()
bool const newError = _error->PendingError();
_error->MergeWithStack();
if (newError)
- return false;
+ return _error->ReturnError();
if (Map.Size() <= 0)
return false;
@@ -132,7 +132,7 @@ bool pkgCacheGenerator::Start()
advoid a problem during a crash */
pkgCacheGenerator::~pkgCacheGenerator()
{
- if (_error->PendingError() == true || Map.validData() == false)
+ if (Map.validData() == false)
return;
if (Map.Sync() == false)
return;
@@ -175,6 +175,10 @@ void pkgCacheGenerator::ReMap(void const * const oldMap, void const * const newM
i != Dynamic<pkgCache::VerIterator>::toReMap.end(); ++i)
if (std::get<1>(seen.insert(*i)) == true)
(*i)->ReMap(oldMap, newMap);
+ for (std::vector<pkgCache::TagIterator*>::const_iterator i = Dynamic<pkgCache::TagIterator>::toReMap.begin();
+ i != Dynamic<pkgCache::TagIterator>::toReMap.end(); ++i)
+ if (std::get<1>(seen.insert(*i)) == true)
+ (*i)->ReMap(oldMap, newMap);
for (std::vector<pkgCache::DepIterator*>::const_iterator i = Dynamic<pkgCache::DepIterator>::toReMap.begin();
i != Dynamic<pkgCache::DepIterator>::toReMap.end(); ++i)
if (std::get<1>(seen.insert(*i)) == true)
@@ -250,7 +254,7 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
{
string const PackageName = List.Package();
if (PackageName.empty() == true)
- return false;
+ continue;
Counter++;
if (Counter % 100 == 0 && Progress != 0)
@@ -264,24 +268,26 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
{
// package descriptions
if (MergeListGroup(List, PackageName) == false)
- return false;
+ continue;
continue;
}
// Get a pointer to the package structure
pkgCache::PkgIterator Pkg;
Dynamic<pkgCache::PkgIterator> DynPkg(Pkg);
- if (NewPackage(Pkg, PackageName, Arch) == false)
+ if (NewPackage(Pkg, PackageName, Arch) == false) {
// TRANSLATOR: The first placeholder is a package name,
// the other two should be copied verbatim as they include debug info
- return _error->Error(_("Error occurred while processing %s (%s%d)"),
+ _error->Error(_("Error occurred while processing %s (%s%d)"),
PackageName.c_str(), "NewPackage", 1);
+ continue;
+ }
if (Version.empty() == true)
{
if (MergeListPackage(List, Pkg) == false)
- return false;
+ continue;
}
else
{
@@ -1274,6 +1280,38 @@ bool pkgCacheGenerator::SelectReleaseFile(const string &File,const string &Site,
return true;
}
/*}}}*/
+// ListParser::NewTag - Create a Tag element /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool pkgCacheListParser::NewTag(pkgCache::VerIterator &Ver,
+ const char *NameStart,
+ unsigned int NameSize)
+{
+ return Owner->NewTag(Ver, NameStart, NameSize);
+}
+bool pkgCacheGenerator::NewTag(pkgCache::VerIterator &Ver,
+ const char *NameStart,
+ unsigned int NameSize)
+{
+ // Get a structure
+ map_pointer_t const idxTag = AllocateInMap(sizeof(pkgCache::Tag));
+ if (unlikely(idxTag == 0))
+ return false;
+
+ // Fill it in
+ pkgCache::TagIterator Tg(Cache,Cache.TagP + idxTag);
+ map_pointer_t const idxName = StoreString(TAG,NameStart,NameSize);
+ if (idxName == 0)
+ return false;
+ Tg->Name = idxName;
+
+ Tg->NextTag = Ver->TagList;
+ Ver->TagList = Tg.Index();
+ Cache.HeaderP->TagCount++;
+
+ return true;
+}
+ /*}}}*/
// CacheGenerator::SelectFile - Select the current file being parsed /*{{{*/
// ---------------------------------------------------------------------
/* This is used to select which file is to be associated with all newly
@@ -1342,6 +1380,7 @@ map_stringitem_t pkgCacheGenerator::StoreString(enum StringType const type, cons
case PKGNAME: strings = &strPkgNames; break;
case VERSIONNUMBER: strings = &strVersions; break;
case SECTION: strings = &strSections; break;
+ case TAG: strings = &strTags; break;
default: _error->Fatal("Unknown enum type used for string storage of '%.*s'", Size, S); return 0;
}
@@ -1401,7 +1440,7 @@ static bool CheckValidity(FileFd &CacheFile, std::string const &CacheFileName,
{
if (Debug == true)
std::clog << "Errors are pending or Map is empty() for " << CacheFileName << std::endl;
- return false;
+ return _error->ReturnError();
}
std::unique_ptr<bool[]> RlsVisited(new bool[Cache.HeaderP->ReleaseFileCount]);
@@ -1481,7 +1520,7 @@ static bool CheckValidity(FileFd &CacheFile, std::string const &CacheFileName,
std::clog << "Validity failed because of pending errors:" << std::endl;
_error->DumpErrors(std::clog, GlobalError::DEBUG, false);
}
- return false;
+ return _error->ReturnError();
}
if (OutMap != 0)
@@ -1519,16 +1558,14 @@ static map_filesize_t ComputeSize(pkgSourceList const * const List, FileIterator
}
/*}}}*/
// BuildCache - Merge the list of index files into the cache /*{{{*/
-static bool BuildCache(pkgCacheGenerator &Gen,
+static void BuildCache(pkgCacheGenerator &Gen,
OpProgress * const Progress,
map_filesize_t &CurrentSize,map_filesize_t TotalSize,
pkgSourceList const * const List,
FileIterator const Start, FileIterator const End)
{
- bool mergeFailure = false;
-
auto const indexFileMerge = [&](pkgIndexFile * const I) {
- if (I->HasPackages() == false || mergeFailure)
+ if (I->HasPackages() == false)
return;
if (I->Exists() == false)
@@ -1546,8 +1583,10 @@ static bool BuildCache(pkgCacheGenerator &Gen,
Progress->OverallProgress(CurrentSize, TotalSize, Size, _("Reading package lists"));
CurrentSize += Size;
- if (I->Merge(Gen,Progress) == false)
- mergeFailure = true;
+ if (I->Merge(Gen,Progress) == false) {
+ _error->ReturnError();
+ return;
+ }
};
if (List != NULL)
@@ -1561,14 +1600,14 @@ static bool BuildCache(pkgCacheGenerator &Gen,
continue;
}
- if ((*i)->Merge(Gen, Progress) == false)
- return false;
+ if ((*i)->Merge(Gen, Progress) == false) {
+ _error->ReturnError();
+ continue;
+ }
std::vector <pkgIndexFile *> *Indexes = (*i)->GetIndexFiles();
if (Indexes != NULL)
std::for_each(Indexes->begin(), Indexes->end(), indexFileMerge);
- if (mergeFailure)
- return false;
}
}
@@ -1576,10 +1615,7 @@ static bool BuildCache(pkgCacheGenerator &Gen,
{
Gen.SelectReleaseFile("", "");
std::for_each(Start, End, indexFileMerge);
- if (mergeFailure)
- return false;
}
- return true;
}
/*}}}*/
// CacheGenerator::MakeStatusCache - Construct the status cache /*{{{*/
@@ -1638,7 +1674,7 @@ static bool loadBackMMapFromFile(std::unique_ptr<pkgCacheGenerator> &Gen,
bool const newError = _error->PendingError();
_error->MergeWithStack();
if (alloc == 0 && newError)
- return false;
+ return _error->ReturnError();
if (CacheF.Read((unsigned char *)Map->Data() + alloc, CacheF.Size()) == false)
return false;
Gen.reset(new pkgCacheGenerator(Map.get(),Progress));
@@ -1754,9 +1790,8 @@ bool pkgCacheGenerator::MakeStatusCache(pkgSourceList &List,OpProgress *Progress
return false;
TotalSize += ComputeSize(&List, Files.begin(),Files.end());
- if (BuildCache(*Gen, Progress, CurrentSize, TotalSize, &List,
- Files.end(),Files.end()) == false)
- return false;
+ BuildCache(*Gen, Progress, CurrentSize, TotalSize, &List,
+ Files.end(),Files.end());
if (Writeable == true && SrcCacheFileName.empty() == false)
if (writeBackMMapToFile(Gen.get(), Map.get(), SrcCacheFileName) == false)
@@ -1767,9 +1802,8 @@ bool pkgCacheGenerator::MakeStatusCache(pkgSourceList &List,OpProgress *Progress
{
if (Debug == true)
std::clog << "Building status cache in pkgcache.bin now" << std::endl;
- if (BuildCache(*Gen, Progress, CurrentSize, TotalSize, NULL,
- Files.begin(), Files.end()) == false)
- return false;
+ BuildCache(*Gen, Progress, CurrentSize, TotalSize, NULL,
+ Files.begin(), Files.end());
if (Writeable == true && CacheFileName.empty() == false)
if (writeBackMMapToFile(Gen.get(), Map.get(), CacheFileName) == false)
@@ -1790,9 +1824,8 @@ bool pkgCacheGenerator::MakeStatusCache(pkgSourceList &List,OpProgress *Progress
}
Files = List.GetVolatileFiles();
- if (BuildCache(*Gen, Progress, CurrentSize, TotalSize, NULL,
- Files.begin(), Files.end()) == false)
- return false;
+ BuildCache(*Gen, Progress, CurrentSize, TotalSize, NULL,
+ Files.begin(), Files.end());
}
if (OutMap != nullptr)
@@ -1829,14 +1862,15 @@ bool pkgCacheGenerator::MakeOnlyStatusCache(OpProgress *Progress,DynamicMMap **O
if (Progress != NULL)
Progress->OverallProgress(0,1,1,_("Reading package lists"));
pkgCacheGenerator Gen(Map.get(),Progress);
- if (Gen.Start() == false || _error->PendingError() == true)
- return false;
- if (BuildCache(Gen,Progress,CurrentSize,TotalSize, NULL,
- Files.begin(), Files.end()) == false)
+ if (Gen.Start() == false)
return false;
-
if (_error->PendingError() == true)
- return false;
+ return _error->ReturnError();
+ BuildCache(Gen,Progress,CurrentSize,TotalSize, NULL,
+ Files.begin(), Files.end());
+ // We've passed the point of no return
+ _error->ReturnError();
+
*OutMap = Map.release();
return true;
diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h
index e11e97e09..44c54269d 100644
--- a/apt-pkg/pkgcachegen.h
+++ b/apt-pkg/pkgcachegen.h
@@ -77,6 +77,7 @@ class APT_HIDDEN pkgCacheGenerator /*{{{*/
std::unordered_set<string_pointer, hash> strPkgNames;
std::unordered_set<string_pointer, hash> strVersions;
std::unordered_set<string_pointer, hash> strSections;
+ std::unordered_set<string_pointer, hash> strTags;
#endif
friend class pkgCacheListParser;
@@ -127,10 +128,11 @@ class APT_HIDDEN pkgCacheGenerator /*{{{*/
uint8_t const Type, map_pointer_t* &OldDepLast);
bool NewProvides(pkgCache::VerIterator &Ver, pkgCache::PkgIterator &Pkg,
map_stringitem_t const ProvidesVersion, uint8_t const Flags);
+ bool NewTag(pkgCache::VerIterator &Ver,const char *NameStart,unsigned int NameSize);
public:
- enum StringType { MIXED, PKGNAME, VERSIONNUMBER, SECTION };
+ enum StringType { MIXED, PKGNAME, VERSIONNUMBER, SECTION, TAG };
map_stringitem_t StoreString(StringType const type, const char * S, unsigned int const Size);
#ifdef APT_PKG_EXPOSE_STRING_VIEW
@@ -208,6 +210,7 @@ class APT_HIDDEN pkgCacheListParser
uint8_t const Flags);
bool NewProvidesAllArch(pkgCache::VerIterator &Ver, APT::StringView Package,
APT::StringView Version, uint8_t const Flags);
+ bool NewTag(pkgCache::VerIterator &Ver,const char *NameStart,unsigned int NameSize);
#endif
public:
diff --git a/apt-pkg/pkgrecords.h b/apt-pkg/pkgrecords.h
index 6d1342d45..f78a6229f 100644
--- a/apt-pkg/pkgrecords.h
+++ b/apt-pkg/pkgrecords.h
@@ -91,6 +91,7 @@ class pkgRecords::Parser /*{{{*/
std::string LongDesc() {return LongDesc("");};
virtual std::string Name() {return std::string();};
+ virtual std::string Display() {return std::string();}
virtual std::string Homepage() {return std::string();}
// An arbitrary custom field
@@ -99,6 +100,9 @@ class pkgRecords::Parser /*{{{*/
// The record in binary form
virtual void GetRec(const char *&Start,const char *&Stop) {Start = Stop = 0;};
+ // Locate a tag
+ virtual bool Find(const char *Tag,const char *&Start, const char *&End) {Start = End = 0; return false;};
+
Parser();
virtual ~Parser();
diff --git a/apt-pkg/policy.cc b/apt-pkg/policy.cc
index 7986aa506..614539266 100644
--- a/apt-pkg/policy.cc
+++ b/apt-pkg/policy.cc
@@ -333,7 +333,7 @@ bool ReadPinDir(pkgPolicy &Plcy,string Dir)
bool const PendingErrors = _error->PendingError();
_error->MergeWithStack();
if (PendingErrors)
- return false;
+ return _error->ReturnError();
// Read the files
bool good = true;
@@ -415,6 +415,7 @@ bool ReadPinFile(pkgPolicy &Plcy,string File)
if (priority < std::numeric_limits<short>::min() ||
priority > std::numeric_limits<short>::max() ||
newError) {
+ _error->ReturnError();
return _error->Error(_("%s: Value %s is outside the range of valid pin priorities (%d to %d)"),
File.c_str(), Tags.FindS("Pin-Priority").c_str(),
std::numeric_limits<short>::min(),
diff --git a/apt-pkg/rawmemchr.cc b/apt-pkg/rawmemchr.cc
new file mode 100644
index 000000000..8f7669b6c
--- /dev/null
+++ b/apt-pkg/rawmemchr.cc
@@ -0,0 +1,139 @@
+/* Searching in a string.
+ Copyright (C) 2008-2015 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#ifndef HAVE_RAWMEMCHR
+
+/* Specification. */
+#include <string.h>
+
+/* Find the first occurrence of C in S. */
+extern "C" void *
+rawmemchr (const void *s, int c_in)
+{
+ /* On 32-bit hardware, choosing longword to be a 32-bit unsigned
+ long instead of a 64-bit uintmax_t tends to give better
+ performance. On 64-bit hardware, unsigned long is generally 64
+ bits already. Change this typedef to experiment with
+ performance. */
+ typedef unsigned long int longword;
+
+ const unsigned char *char_ptr;
+ const longword *longword_ptr;
+ longword repeated_one;
+ longword repeated_c;
+ unsigned char c;
+
+ c = (unsigned char) c_in;
+
+ /* Handle the first few bytes by reading one byte at a time.
+ Do this until CHAR_PTR is aligned on a longword boundary. */
+ for (char_ptr = (const unsigned char *) s;
+ (size_t) char_ptr % sizeof (longword) != 0;
+ ++char_ptr)
+ if (*char_ptr == c)
+ return (void *) char_ptr;
+
+ longword_ptr = (const longword *) char_ptr;
+
+ /* All these elucidatory comments refer to 4-byte longwords,
+ but the theory applies equally well to any size longwords. */
+
+ /* Compute auxiliary longword values:
+ repeated_one is a value which has a 1 in every byte.
+ repeated_c has c in every byte. */
+ repeated_one = 0x01010101;
+ repeated_c = c | (c << 8);
+ repeated_c |= repeated_c << 16;
+ if (0xffffffffU < (longword) -1)
+ {
+ repeated_one |= repeated_one << 31 << 1;
+ repeated_c |= repeated_c << 31 << 1;
+ if (8 < sizeof (longword))
+ {
+ size_t i;
+
+ for (i = 64; i < sizeof (longword) * 8; i *= 2)
+ {
+ repeated_one |= repeated_one << i;
+ repeated_c |= repeated_c << i;
+ }
+ }
+ }
+
+ /* Instead of the traditional loop which tests each byte, we will
+ test a longword at a time. The tricky part is testing if *any of
+ the four* bytes in the longword in question are equal to NUL or
+ c. We first use an xor with repeated_c. This reduces the task
+ to testing whether *any of the four* bytes in longword1 is zero.
+
+ We compute tmp =
+ ((longword1 - repeated_one) & ~longword1) & (repeated_one << 7).
+ That is, we perform the following operations:
+ 1. Subtract repeated_one.
+ 2. & ~longword1.
+ 3. & a mask consisting of 0x80 in every byte.
+ Consider what happens in each byte:
+ - If a byte of longword1 is zero, step 1 and 2 transform it into 0xff,
+ and step 3 transforms it into 0x80. A carry can also be propagated
+ to more significant bytes.
+ - If a byte of longword1 is nonzero, let its lowest 1 bit be at
+ position k (0 <= k <= 7); so the lowest k bits are 0. After step 1,
+ the byte ends in a single bit of value 0 and k bits of value 1.
+ After step 2, the result is just k bits of value 1: 2^k - 1. After
+ step 3, the result is 0. And no carry is produced.
+ So, if longword1 has only non-zero bytes, tmp is zero.
+ Whereas if longword1 has a zero byte, call j the position of the least
+ significant zero byte. Then the result has a zero at positions 0, ...,
+ j-1 and a 0x80 at position j. We cannot predict the result at the more
+ significant bytes (positions j+1..3), but it does not matter since we
+ already have a non-zero bit at position 8*j+7.
+
+ The test whether any byte in longword1 is zero is equivalent
+ to testing whether tmp is nonzero.
+
+ This test can read beyond the end of a string, depending on where
+ C_IN is encountered. However, this is considered safe since the
+ initialization phase ensured that the read will be aligned,
+ therefore, the read will not cross page boundaries and will not
+ cause a fault. */
+
+ while (1)
+ {
+ longword longword1 = *longword_ptr ^ repeated_c;
+
+ if ((((longword1 - repeated_one) & ~longword1)
+ & (repeated_one << 7)) != 0)
+ break;
+ longword_ptr++;
+ }
+
+ char_ptr = (const unsigned char *) longword_ptr;
+
+ /* At this point, we know that one of the sizeof (longword) bytes
+ starting at char_ptr is == c. On little-endian machines, we
+ could determine the first such byte without any further memory
+ accesses, just by looking at the tmp result from the last loop
+ iteration. But this does not work on big-endian machines.
+ Choose code that works in both cases. */
+
+ char_ptr = (unsigned char *) longword_ptr;
+ while (*char_ptr != c)
+ char_ptr++;
+ return (void *) char_ptr;
+}
+#endif
diff --git a/apt-pkg/strchrnul.cc b/apt-pkg/strchrnul.cc
new file mode 100644
index 000000000..b68b8501b
--- /dev/null
+++ b/apt-pkg/strchrnul.cc
@@ -0,0 +1,147 @@
+/* Searching in a string.
+ Copyright (C) 2003, 2007-2015 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#ifndef HAVE_STRCHRNUL
+
+/* Specification. */
+#include <string.h>
+
+#include <apt-pkg/missing.h>
+
+/* Find the first occurrence of C in S or the final NUL byte. */
+extern "C" char *
+strchrnul (const char *s, int c_in)
+{
+ /* On 32-bit hardware, choosing longword to be a 32-bit unsigned
+ long instead of a 64-bit uintmax_t tends to give better
+ performance. On 64-bit hardware, unsigned long is generally 64
+ bits already. Change this typedef to experiment with
+ performance. */
+ typedef unsigned long int longword;
+
+ const unsigned char *char_ptr;
+ const longword *longword_ptr;
+ longword repeated_one;
+ longword repeated_c;
+ unsigned char c;
+
+ c = (unsigned char) c_in;
+ if (!c)
+ return (char*) rawmemchr (s, 0);
+
+ /* Handle the first few bytes by reading one byte at a time.
+ Do this until CHAR_PTR is aligned on a longword boundary. */
+ for (char_ptr = (const unsigned char *) s;
+ (size_t) char_ptr % sizeof (longword) != 0;
+ ++char_ptr)
+ if (!*char_ptr || *char_ptr == c)
+ return (char *) char_ptr;
+
+ longword_ptr = (const longword *) char_ptr;
+
+ /* All these elucidatory comments refer to 4-byte longwords,
+ but the theory applies equally well to any size longwords. */
+
+ /* Compute auxiliary longword values:
+ repeated_one is a value which has a 1 in every byte.
+ repeated_c has c in every byte. */
+ repeated_one = 0x01010101;
+ repeated_c = c | (c << 8);
+ repeated_c |= repeated_c << 16;
+ if (0xffffffffU < (longword) -1)
+ {
+ repeated_one |= repeated_one << 31 << 1;
+ repeated_c |= repeated_c << 31 << 1;
+ if (8 < sizeof (longword))
+ {
+ size_t i;
+
+ for (i = 64; i < sizeof (longword) * 8; i *= 2)
+ {
+ repeated_one |= repeated_one << i;
+ repeated_c |= repeated_c << i;
+ }
+ }
+ }
+
+ /* Instead of the traditional loop which tests each byte, we will
+ test a longword at a time. The tricky part is testing if *any of
+ the four* bytes in the longword in question are equal to NUL or
+ c. We first use an xor with repeated_c. This reduces the task
+ to testing whether *any of the four* bytes in longword1 or
+ longword2 is zero.
+
+ Let's consider longword1. We compute tmp =
+ ((longword1 - repeated_one) & ~longword1) & (repeated_one << 7).
+ That is, we perform the following operations:
+ 1. Subtract repeated_one.
+ 2. & ~longword1.
+ 3. & a mask consisting of 0x80 in every byte.
+ Consider what happens in each byte:
+ - If a byte of longword1 is zero, step 1 and 2 transform it into 0xff,
+ and step 3 transforms it into 0x80. A carry can also be propagated
+ to more significant bytes.
+ - If a byte of longword1 is nonzero, let its lowest 1 bit be at
+ position k (0 <= k <= 7); so the lowest k bits are 0. After step 1,
+ the byte ends in a single bit of value 0 and k bits of value 1.
+ After step 2, the result is just k bits of value 1: 2^k - 1. After
+ step 3, the result is 0. And no carry is produced.
+ So, if longword1 has only non-zero bytes, tmp is zero.
+ Whereas if longword1 has a zero byte, call j the position of the least
+ significant zero byte. Then the result has a zero at positions 0, ...,
+ j-1 and a 0x80 at position j. We cannot predict the result at the more
+ significant bytes (positions j+1..3), but it does not matter since we
+ already have a non-zero bit at position 8*j+7.
+
+ The test whether any byte in longword1 or longword2 is zero is equivalent
+ to testing whether tmp1 is nonzero or tmp2 is nonzero. We can combine
+ this into a single test, whether (tmp1 | tmp2) is nonzero.
+
+ This test can read more than one byte beyond the end of a string,
+ depending on where the terminating NUL is encountered. However,
+ this is considered safe since the initialization phase ensured
+ that the read will be aligned, therefore, the read will not cross
+ page boundaries and will not cause a fault. */
+
+ while (1)
+ {
+ longword longword1 = *longword_ptr ^ repeated_c;
+ longword longword2 = *longword_ptr;
+
+ if (((((longword1 - repeated_one) & ~longword1)
+ | ((longword2 - repeated_one) & ~longword2))
+ & (repeated_one << 7)) != 0)
+ break;
+ longword_ptr++;
+ }
+
+ char_ptr = (const unsigned char *) longword_ptr;
+
+ /* At this point, we know that one of the sizeof (longword) bytes
+ starting at char_ptr is == 0 or == c. On little-endian machines,
+ we could determine the first such byte without any further memory
+ accesses, just by looking at the tmp result from the last loop
+ iteration. But this does not work on big-endian machines.
+ Choose code that works in both cases. */
+
+ char_ptr = (unsigned char *) longword_ptr;
+ while (*char_ptr && (*char_ptr != c))
+ char_ptr++;
+ return (char *) char_ptr;
+}
+#endif
diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc
index 1e7f2867c..5f39e5757 100644
--- a/apt-pkg/tagfile.cc
+++ b/apt-pkg/tagfile.cc
@@ -12,6 +12,7 @@
// Include Files /*{{{*/
#include <config.h>
+#include <apt-pkg/mmap.h>
#include <apt-pkg/error.h>
#include <apt-pkg/fileutl.h>
#include <apt-pkg/string_view.h>
@@ -36,10 +37,11 @@ using APT::StringView;
class APT_HIDDEN pkgTagFilePrivate /*{{{*/
{
public:
- void Reset(FileFd * const pFd, unsigned long long const pSize, pkgTagFile::Flags const pFlags)
+ void Reset(FileFd * const pFd, pkgTagFile::Flags const pFlags)
{
- if (Buffer != NULL)
- free(Buffer);
+ if (Map != NULL)
+ delete Map;
+ Map = NULL;
Buffer = NULL;
Fd = pFd;
Flags = pFlags;
@@ -47,14 +49,11 @@ public:
End = NULL;
Done = false;
iOffset = 0;
- Size = pSize;
- isCommentedLine = false;
- chunks.clear();
}
- pkgTagFilePrivate(FileFd * const pFd, unsigned long long const Size, pkgTagFile::Flags const pFlags) : Buffer(NULL)
+ pkgTagFilePrivate(FileFd * const pFd, pkgTagFile::Flags const pFlags) : Map(NULL)
{
- Reset(pFd, Size, pFlags);
+ Reset(pFd, pFlags);
}
FileFd * Fd;
pkgTagFile::Flags Flags;
@@ -63,20 +62,12 @@ public:
char *End;
bool Done;
unsigned long long iOffset;
- unsigned long long Size;
- bool isCommentedLine;
- struct FileChunk
- {
- bool const good;
- size_t length;
- FileChunk(bool const pgood, size_t const plength) : good(pgood), length(plength) {}
- };
- std::list<FileChunk> chunks;
+ MMap *Map;
~pkgTagFilePrivate()
{
- if (Buffer != NULL)
- free(Buffer);
+ if (Map != NULL)
+ delete Map;
}
};
/*}}}*/
@@ -115,42 +106,38 @@ static unsigned long BetaHash(const char *Text, size_t Length) /*{{{*/
/*}}}*/
// TagFile::pkgTagFile - Constructor /*{{{*/
-pkgTagFile::pkgTagFile(FileFd * const pFd,pkgTagFile::Flags const pFlags, unsigned long long const Size)
- : d(new pkgTagFilePrivate(pFd, Size + 4, pFlags))
+pkgTagFile::pkgTagFile(FileFd * const pFd,pkgTagFile::Flags const pFlags)
+ : d(new pkgTagFilePrivate(pFd, pFlags))
{
- Init(pFd, pFlags, Size);
+ Init(pFd, pFlags);
}
-pkgTagFile::pkgTagFile(FileFd * const pFd,unsigned long long const Size)
- : pkgTagFile(pFd, pkgTagFile::STRICT, Size)
+pkgTagFile::pkgTagFile(FileFd * const pFd)
+ : pkgTagFile(pFd, pkgTagFile::STRICT)
{
}
-void pkgTagFile::Init(FileFd * const pFd, pkgTagFile::Flags const pFlags, unsigned long long Size)
+void pkgTagFile::Init(FileFd * const pFd, pkgTagFile::Flags const pFlags)
{
- /* 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->Reset(pFd, Size, pFlags);
-
- if (d->Fd->IsOpen() == false)
- d->Start = d->End = d->Buffer = 0;
- else
- d->Buffer = (char*)malloc(sizeof(char) * Size);
+ d->Reset(pFd, pFlags);
+
+ if (d->Fd->IsOpen() == false || d->Fd->Size() == 0)
+ _error->Discard();
+ else {
+ d->Map = new MMap(*d->Fd, MMap::ReadOnly);
+ d->Buffer = static_cast<char *>(d->Map->Data());
+ }
if (d->Buffer == NULL)
d->Done = true;
- else
+ else {
d->Done = false;
+ d->End = d->Buffer + d->Map->Size();
+ }
- d->Start = d->End = d->Buffer;
- d->iOffset = 0;
- if (d->Done == false)
- Fill();
+ d->Start = d->Buffer;
}
-void pkgTagFile::Init(FileFd * const pFd,unsigned long long Size)
+void pkgTagFile::Init(FileFd * const pFd)
{
- Init(pFd, pkgTagFile::STRICT, Size);
+ Init(pFd, pkgTagFile::STRICT);
}
/*}}}*/
// TagFile::~pkgTagFile - Destructor /*{{{*/
@@ -165,36 +152,6 @@ APT_PURE unsigned long pkgTagFile::Offset()
return d->iOffset;
}
/*}}}*/
-// TagFile::Resize - Resize the internal buffer /*{{{*/
-// ---------------------------------------------------------------------
-/* Resize the internal buffer (double it in size). Fail if a maximum size
- * size is reached.
- */
-bool pkgTagFile::Resize()
-{
- // 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
- char* const newBuffer = static_cast<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;
- d->End = d->Start + EndSize;
- return true;
-}
- /*}}}*/
// TagFile::Step - Advance to the next section /*{{{*/
// ---------------------------------------------------------------------
/* If the Section Scanner fails we refill the buffer and try again.
@@ -203,225 +160,18 @@ bool pkgTagFile::Resize(unsigned long long const newSize)
*/
bool pkgTagFile::Step(pkgTagSection &Tag)
{
- if(Tag.Scan(d->Start,d->End - d->Start) == false)
+ if(Tag.Scan(d->Start,d->End - d->Start,(d->Flags & SUPPORT_COMMENTS) != 0) == false)
{
- do
- {
- if (Fill() == false)
- return false;
-
- if(Tag.Scan(d->Start,d->End - d->Start, false))
- break;
-
- if (Resize() == false)
- return _error->Error(_("Unable to parse package file %s (%d)"),
+ if (d->Start == d->End)
+ return false;
+ else
+ return _error->Warning(_("Unable to parse package file %s (%d)"),
d->Fd->Name().c_str(), 1);
-
- } while (Tag.Scan(d->Start,d->End - d->Start, false) == false);
}
size_t tagSize = Tag.size();
d->Start += tagSize;
-
- if ((d->Flags & pkgTagFile::SUPPORT_COMMENTS) == 0)
- d->iOffset += tagSize;
- else
- {
- auto first = d->chunks.begin();
- for (; first != d->chunks.end(); ++first)
- {
- if (first->good == false)
- d->iOffset += first->length;
- else
- {
- if (tagSize < first->length)
- {
- first->length -= tagSize;
- d->iOffset += tagSize;
- break;
- }
- else
- {
- tagSize -= first->length;
- d->iOffset += first->length;
- }
- }
- }
- d->chunks.erase(d->chunks.begin(), first);
- }
-
- if ((d->Flags & pkgTagFile::SUPPORT_COMMENTS) == 0 || Tag.Count() != 0)
- {
- Tag.Trim();
- return true;
- }
- return Step(Tag);
-}
- /*}}}*/
-// TagFile::Fill - Top up the buffer /*{{{*/
-// ---------------------------------------------------------------------
-/* This takes the bit at the end of the buffer and puts it at the start
- then fills the rest from the file */
-static bool FillBuffer(pkgTagFilePrivate * const d)
-{
- unsigned long long Actual = 0;
- // See if only a bit of the file is left
- 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 != dataSize)
- d->Done = true;
- d->End += Actual;
- return true;
-}
-static void RemoveCommentsFromBuffer(pkgTagFilePrivate * const d)
-{
- // look for valid comments in the buffer
- char * good_start = nullptr, * bad_start = nullptr;
- char * current = d->Start;
- if (d->isCommentedLine == false)
- {
- if (d->Start == d->Buffer)
- {
- // the start of the buffer is a newline as a record can't start
- // in the middle of a line by definition.
- if (*d->Start == '#')
- {
- d->isCommentedLine = true;
- ++current;
- if (current > d->End)
- d->chunks.emplace_back(false, 1);
- }
- }
- if (d->isCommentedLine == false)
- good_start = d->Start;
- else
- bad_start = d->Start;
- }
- else
- bad_start = d->Start;
-
- std::vector<std::pair<char*, size_t>> good_parts;
- while (current <= d->End)
- {
- size_t const restLength = (d->End - current);
- if (d->isCommentedLine == false)
- {
- current = static_cast<char*>(memchr(current, '#', restLength));
- if (current == nullptr)
- {
- size_t const goodLength = d->End - good_start;
- d->chunks.emplace_back(true, goodLength);
- if (good_start != d->Start)
- good_parts.push_back(std::make_pair(good_start, goodLength));
- break;
- }
- bad_start = current;
- --current;
- // ensure that this is really a comment and not a '#' in the middle of a line
- if (*current == '\n')
- {
- size_t const goodLength = (current - good_start) + 1;
- d->chunks.emplace_back(true, goodLength);
- good_parts.push_back(std::make_pair(good_start, goodLength));
- good_start = nullptr;
- d->isCommentedLine = true;
- }
- current += 2;
- }
- else // the current line is a comment
- {
- current = static_cast<char*>(memchr(current, '\n', restLength));
- if (current == nullptr)
- {
- d->chunks.emplace_back(false, (d->End - bad_start));
- break;
- }
- ++current;
- // is the next line a comment, too?
- if (current >= d->End || *current != '#')
- {
- d->chunks.emplace_back(false, (current - bad_start));
- good_start = current;
- bad_start = nullptr;
- d->isCommentedLine = false;
- }
- ++current;
- }
- }
-
- if (good_parts.empty() == false)
- {
- // we found comments, so move later parts over them
- current = d->Start;
- for (auto const &good: good_parts)
- {
- memmove(current, good.first, good.second);
- current += good.second;
- }
- d->End = current;
- }
-
- if (d->isCommentedLine == true)
- {
- // deal with a buffer containing only comments
- // or an (unfinished) comment at the end
- if (good_parts.empty() == true)
- d->End = d->Start;
- else
- d->Start = d->End;
- }
- else
- {
- // the buffer was all comment, but ended with the buffer
- if (good_parts.empty() == true && good_start >= d->End)
- d->End = d->Start;
- else
- d->Start = d->End;
- }
-}
-bool pkgTagFile::Fill()
-{
- unsigned long long const EndSize = d->End - d->Start;
- if (EndSize != 0)
- {
- memmove(d->Buffer,d->Start,EndSize);
- d->Start = d->End = d->Buffer + EndSize;
- }
- else
- d->Start = d->End = d->Buffer;
-
- unsigned long long Actual = 0;
- while (d->Done == false && d->Size > (Actual + 1))
- {
- if (FillBuffer(d) == false)
- return false;
- if ((d->Flags & pkgTagFile::SUPPORT_COMMENTS) != 0)
- RemoveCommentsFromBuffer(d);
- Actual = d->End - d->Buffer;
- }
- d->Start = d->Buffer;
-
- if (d->Done == true)
- {
- if (EndSize <= 3 && Actual == 0)
- return false;
- if (d->Size - (d->End - d->Buffer) < 4)
- return true;
-
- // Append a double new line if one does not exist
- unsigned int LineCount = 0;
- for (const char *E = d->End - 1; E - d->End < 6 && (*E == '\n' || *E == '\r'); E--)
- if (*E == '\n')
- ++LineCount;
- if (LineCount < 2)
- {
- if (static_cast<unsigned long long>(d->End - d->Buffer) >= d->Size)
- Resize(d->Size + 3);
- for (; LineCount < 2; ++LineCount)
- *d->End++ = '\n';
- }
- }
+ d->iOffset += tagSize;
return true;
}
/*}}}*/
@@ -431,43 +181,16 @@ bool pkgTagFile::Fill()
that is there */
bool pkgTagFile::Jump(pkgTagSection &Tag,unsigned long long Offset)
{
- if ((d->Flags & pkgTagFile::SUPPORT_COMMENTS) == 0 &&
- // We are within a buffer space of the next hit..
- Offset >= d->iOffset && d->iOffset + (d->End - d->Start) > Offset)
- {
- unsigned long long Dist = Offset - d->iOffset;
- d->Start += Dist;
- d->iOffset += Dist;
- // if we have seen the end, don't ask for more
- if (d->Done == true)
- return Tag.Scan(d->Start, d->End - d->Start);
- else
- return Step(Tag);
- }
+ unsigned int Size(d->Map->Size());
+ if (Offset >= Size)
+ return false;
// Reposition and reload..
d->iOffset = Offset;
d->Done = false;
- if (d->Fd->Seek(Offset) == false)
- return false;
- d->End = d->Start = d->Buffer;
- d->isCommentedLine = false;
- d->chunks.clear();
-
- if (Fill() == false)
- return false;
+ d->Start = d->Buffer + d->iOffset;
- if (Tag.Scan(d->Start, d->End - d->Start) == true)
- return true;
-
- // This appends a double new line (for the real eof handling)
- if (Fill() == false)
- return false;
-
- if (Tag.Scan(d->Start, d->End - d->Start, false) == false)
- return _error->Error(_("Unable to parse package file %s (%d)"),d->Fd->Name().c_str(), 2);
-
- return true;
+ return Step(Tag);
}
/*}}}*/
// pkgTagSection::pkgTagSection - Constructor /*{{{*/
@@ -483,32 +206,20 @@ pkgTagSection::pkgTagSection()
APT_IGNORE_DEPRECATED_POP
/*}}}*/
// TagSection::Scan - Scan for the end of the header information /*{{{*/
-bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength, bool const Restart)
+bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength,bool const SupportComments)
{
Section = Start;
const char *End = Start + MaxLength;
- if (Restart == false && d->Tags.empty() == false)
- {
- Stop = Section + d->Tags.back().StartTag;
- if (End <= Stop)
- return false;
- Stop = (const char *)memchr(Stop,'\n',End - Stop);
- if (Stop == NULL)
- return false;
- ++Stop;
- }
- else
+ Stop = Section;
+ if (d->Tags.empty() == false)
{
- Stop = Section;
- if (d->Tags.empty() == false)
- {
- memset(&AlphaIndexes, 0, sizeof(AlphaIndexes));
- memset(&BetaIndexes, 0, sizeof(BetaIndexes));
- d->Tags.clear();
- }
- d->Tags.reserve(0x100);
+ memset(&AlphaIndexes, 0, sizeof(AlphaIndexes));
+ memset(&BetaIndexes, 0, sizeof(BetaIndexes));
+ d->Tags.clear();
}
+ d->Tags.reserve(0x100);
+
unsigned int TagCount = d->Tags.size();
if (Stop == 0)
@@ -520,12 +231,12 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength, bool const R
unsigned int lastTagHash = 0;
while (Stop < End)
{
- TrimRecord(true,End);
+ TrimRecord(true,End,SupportComments);
// this can happen when TrimRecord trims away the entire Record
// (e.g. because it just contains comments)
if(Stop == End)
- return true;
+ goto end;
// Start a new index and add it to the hash
if (isspace_ascii(Stop[0]) == 0)
@@ -564,17 +275,17 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength, bool const R
// find the beginning of the value
Stop = Colon + 1;
for (; Stop < End && isspace_ascii(*Stop) != 0; ++Stop)
- if (*Stop == '\n' && Stop[1] != ' ')
+ if (*Stop == '\n' && (Stop+1 == End || Stop[1] != ' '))
break;
- if (Stop >= End)
- return false;
lastTagData.StartValue = Stop - Section;
}
Stop = (const char *)memchr(Stop,'\n',End - Stop);
- if (Stop == 0)
- return false;
+ if (Stop == 0) {
+ Stop = End;
+ goto end;
+ }
for (; Stop+1 < End && Stop[1] == '\r'; Stop++)
/* nothing */
@@ -582,7 +293,7 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength, bool const R
// Double newline marks the end of the record
if (Stop+1 < End && Stop[1] == '\n')
- {
+ end: {
if (lastTagData.EndTag != 0)
{
if (lastTagKey != Key::Unknown) {
@@ -595,26 +306,32 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength, bool const R
d->Tags.push_back(lastTagData);
}
+ if (d->Tags.empty())
+ return false;
+
pkgTagSectionPrivate::TagData const td(Stop - Section);
d->Tags.push_back(td);
- TrimRecord(false,End);
+ TrimRecord(false,End,SupportComments);
return true;
}
Stop++;
}
- return false;
+ goto end;
}
/*}}}*/
// 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++);
+void pkgTagSection::TrimRecord(bool BeforeRecord, const char*& End, bool SupportComments)
+{ trim:
+ if (BeforeRecord == false)
+ for (; Stop < End && (Stop[0] == '\n' || Stop[0] == '\r'); Stop++);
+ if (SupportComments && Stop < End && Stop[0] == '#') {
+ Stop = (const char*) memchr(Stop,'\n',End-Stop) ?: End;
+ goto trim;
+ }
}
/*}}}*/
// TagSection::Trim - Trim off any trailing garbage /*{{{*/
@@ -624,7 +341,7 @@ void pkgTagSection::Trim()
{
for (; Stop > Section + 2 && (Stop[-2] == '\n' || Stop[-2] == '\r'); Stop--);
}
- /*}}}*/
+
// TagSection::Exists - return True if a tag exists /*{{{*/
bool pkgTagSection::Exists(StringView Tag) const
{
@@ -679,7 +396,7 @@ bool pkgTagSection::FindInternal(unsigned int Pos, const char *&Start,
if (unlikely(Start > End))
return _error->Error("Internal parsing error");
- for (; isspace_ascii(End[-1]) != 0 && End > Start; --End);
+ for (; End > Start && isspace_ascii(End[-1]) != 0; --End);
return true;
}
@@ -1065,14 +782,6 @@ bool pkgTagSection::Write(FileFd &File, char const * const * const Order, std::v
}
/*}}}*/
-void pkgUserTagSection::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);
-}
- /*}}}*/
-
#include "tagfile-order.c"
// TFRewrite - Rewrite a control record /*{{{*/
diff --git a/apt-pkg/tagfile.h b/apt-pkg/tagfile.h
index 8b59c43de..a96262e34 100644
--- a/apt-pkg/tagfile.h
+++ b/apt-pkg/tagfile.h
@@ -138,11 +138,11 @@ class pkgTagSection
* @return \b true if section end was found, \b false otherwise.
* Beware that internal state will be inconsistent if \b false is returned!
*/
- APT_MUSTCHECK bool Scan(const char *Start, unsigned long MaxLength, bool const Restart = true);
+ APT_MUSTCHECK bool Scan(const char *Start, unsigned long MaxLength, bool const SupportComments = true);
inline unsigned long size() const {return Stop - Section;};
void Trim();
- virtual void TrimRecord(bool BeforeRecord, const char* &End);
+ void TrimRecord(bool BeforeRecord, const char* &End, bool SupportComments);
/** \brief amount of Tags in the current section
*
@@ -187,11 +187,6 @@ class pkgTagSection
};
-class APT_DEPRECATED_MSG("Use pkgTagFile with the SUPPORT_COMMENTS flag instead") pkgUserTagSection : public pkgTagSection
-{
- virtual void TrimRecord(bool BeforeRecord, const char* &End) APT_OVERRIDE;
-};
-
/** \class pkgTagFile reads and prepares a deb822 formatted file for parsing
* via #pkgTagSection. The default mode tries to be as fast as possible and
* assumes perfectly valid (machine generated) files like Packages. Support
@@ -200,10 +195,6 @@ class pkgTagFile
{
pkgTagFilePrivate * const d;
- APT_HIDDEN bool Fill();
- APT_HIDDEN bool Resize();
- APT_HIDDEN bool Resize(unsigned long long const newSize);
-
public:
bool Step(pkgTagSection &Section);
@@ -216,11 +207,11 @@ public:
SUPPORT_COMMENTS = 1 << 0,
};
- void Init(FileFd * const F, pkgTagFile::Flags const Flags, unsigned long long Size = 32*1024);
- void Init(FileFd * const F,unsigned long long const Size = 32*1024);
+ void Init(FileFd * const F, pkgTagFile::Flags const Flags);
+ void Init(FileFd * const F);
- pkgTagFile(FileFd * const F, pkgTagFile::Flags const Flags, unsigned long long Size = 32*1024);
- pkgTagFile(FileFd * const F,unsigned long long Size = 32*1024);
+ pkgTagFile(FileFd * const F, pkgTagFile::Flags const Flags);
+ pkgTagFile(FileFd * const F);
virtual ~pkgTagFile();
};