summaryrefslogtreecommitdiff
path: root/apt-pkg/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg/contrib')
-rw-r--r--apt-pkg/contrib/configuration.cc149
-rw-r--r--apt-pkg/contrib/configuration.h2
-rw-r--r--apt-pkg/contrib/fileutl.cc436
-rw-r--r--apt-pkg/contrib/fileutl.h2
-rw-r--r--apt-pkg/contrib/mmap.cc1
-rw-r--r--apt-pkg/contrib/netrc.cc3
-rw-r--r--apt-pkg/contrib/sha2_internal.cc8
-rw-r--r--apt-pkg/contrib/strutl.cc63
8 files changed, 520 insertions, 144 deletions
diff --git a/apt-pkg/contrib/configuration.cc b/apt-pkg/contrib/configuration.cc
index 36866a35a..4de17e3e1 100644
--- a/apt-pkg/contrib/configuration.cc
+++ b/apt-pkg/contrib/configuration.cc
@@ -171,48 +171,60 @@ string Configuration::Find(const char *Name,const char *Default) const
string Configuration::FindFile(const char *Name,const char *Default) const
{
const Item *RootItem = Lookup("RootDir");
- std::string rootDir = (RootItem == 0) ? "" : RootItem->Value;
- if(rootDir.size() > 0 && rootDir[rootDir.size() - 1] != '/')
- rootDir.push_back('/');
+ std::string result = (RootItem == 0) ? "" : RootItem->Value;
+ if(result.empty() == false && result[result.size() - 1] != '/')
+ result.push_back('/');
const Item *Itm = Lookup(Name);
if (Itm == 0 || Itm->Value.empty() == true)
{
- if (Default == 0)
- return rootDir;
- else
- return rootDir + Default;
+ if (Default != 0)
+ result.append(Default);
}
-
- string val = Itm->Value;
- while (Itm->Parent != 0)
+ else
{
- if (Itm->Parent->Value.empty() == true)
+ string val = Itm->Value;
+ while (Itm->Parent != 0)
{
- Itm = Itm->Parent;
- continue;
- }
+ if (Itm->Parent->Value.empty() == true)
+ {
+ Itm = Itm->Parent;
+ continue;
+ }
+
+ // Absolute
+ if (val.length() >= 1 && val[0] == '/')
+ {
+ if (val.compare(0, 9, "/dev/null") == 0)
+ val.erase(9);
+ break;
+ }
- // Absolute
- if (val.length() >= 1 && val[0] == '/')
- break;
+ // ~/foo or ./foo
+ if (val.length() >= 2 && (val[0] == '~' || val[0] == '.') && val[1] == '/')
+ break;
- // ~/foo or ./foo
- if (val.length() >= 2 && (val[0] == '~' || val[0] == '.') && val[1] == '/')
- break;
-
- // ../foo
- if (val.length() >= 3 && val[0] == '.' && val[1] == '.' && val[2] == '/')
- break;
-
- if (Itm->Parent->Value.end()[-1] != '/')
- val.insert(0, "/");
+ // ../foo
+ if (val.length() >= 3 && val[0] == '.' && val[1] == '.' && val[2] == '/')
+ break;
+
+ if (Itm->Parent->Value.end()[-1] != '/')
+ val.insert(0, "/");
- val.insert(0, Itm->Parent->Value);
- Itm = Itm->Parent;
+ val.insert(0, Itm->Parent->Value);
+ Itm = Itm->Parent;
+ }
+ result.append(val);
}
- return rootDir + val;
+ // do some normalisation by removing // and /./ from the path
+ size_t found = string::npos;
+ while ((found = result.find("/./")) != string::npos)
+ result.replace(found, 3, "/");
+ while ((found = result.find("//")) != string::npos)
+ result.replace(found, 2, "/");
+
+ return result;
}
/*}}}*/
// Configuration::FindDir - Find a directory name /*{{{*/
@@ -222,7 +234,12 @@ string Configuration::FindDir(const char *Name,const char *Default) const
{
string Res = FindFile(Name,Default);
if (Res.end()[-1] != '/')
+ {
+ size_t const found = Res.rfind("/dev/null");
+ if (found != string::npos && found == Res.size() - 9)
+ return Res; // /dev/null returning
return Res + '/';
+ }
return Res;
}
/*}}}*/
@@ -482,24 +499,80 @@ bool Configuration::ExistsAny(const char *Name) const
/* Dump the entire configuration space */
void Configuration::Dump(ostream& str)
{
- /* Write out all of the configuration directives by walking the
+ Dump(str, NULL, "%f \"%v\";\n", true);
+}
+void Configuration::Dump(ostream& str, char const * const root,
+ char const * const formatstr, bool const emptyValue)
+{
+ const Configuration::Item* Top = Tree(root);
+ if (Top == 0)
+ return;
+ const Configuration::Item* const Root = (root == NULL) ? NULL : Top;
+ std::vector<std::string> const format = VectorizeString(formatstr, '%');
+
+ /* Write out all of the configuration directives by walking the
configuration tree */
- const Configuration::Item *Top = Tree(0);
- for (; Top != 0;)
- {
- str << Top->FullTag() << " \"" << Top->Value << "\";" << endl;
-
+ do {
+ if (emptyValue == true || Top->Value.empty() == emptyValue)
+ {
+ std::vector<std::string>::const_iterator f = format.begin();
+ str << *f;
+ for (++f; f != format.end(); ++f)
+ {
+ if (f->empty() == true)
+ {
+ ++f;
+ str << '%' << *f;
+ continue;
+ }
+ char const type = (*f)[0];
+ if (type == 'f')
+ str << Top->FullTag();
+ else if (type == 't')
+ str << Top->Tag;
+ else if (type == 'v')
+ str << Top->Value;
+ else if (type == 'F')
+ str << QuoteString(Top->FullTag(), "=\"\n");
+ else if (type == 'T')
+ str << QuoteString(Top->Tag, "=\"\n");
+ else if (type == 'V')
+ str << QuoteString(Top->Value, "=\"\n");
+ else if (type == 'n')
+ str << "\n";
+ else if (type == 'N')
+ str << "\t";
+ else
+ str << '%' << type;
+ str << f->c_str() + 1;
+ }
+ }
+
if (Top->Child != 0)
{
Top = Top->Child;
continue;
}
-
+
while (Top != 0 && Top->Next == 0)
Top = Top->Parent;
if (Top != 0)
Top = Top->Next;
- }
+
+ if (Root != NULL)
+ {
+ const Configuration::Item* I = Top;
+ while(I != 0)
+ {
+ if (I == Root)
+ break;
+ else
+ I = I->Parent;
+ }
+ if (I == 0)
+ break;
+ }
+ } while (Top != 0);
}
/*}}}*/
diff --git a/apt-pkg/contrib/configuration.h b/apt-pkg/contrib/configuration.h
index 4c2e75041..ea94c2fe6 100644
--- a/apt-pkg/contrib/configuration.h
+++ b/apt-pkg/contrib/configuration.h
@@ -103,6 +103,8 @@ class Configuration
inline void Dump() { Dump(std::clog); };
void Dump(std::ostream& str);
+ void Dump(std::ostream& str, char const * const root,
+ char const * const format, bool const emptyValue);
Configuration(const Item *Root);
Configuration();
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc
index 529e7d655..c7f78cdfb 100644
--- a/apt-pkg/contrib/fileutl.cc
+++ b/apt-pkg/contrib/fileutl.cc
@@ -44,14 +44,11 @@
#include <set>
#include <algorithm>
-// FIXME: Compressor Fds have some speed disadvantages and are a bit buggy currently,
-// so while the current implementation satisfies the testcases it is not a real option
-// to disable it for now
-#define APT_USE_ZLIB 1
-#if APT_USE_ZLIB
-#include <zlib.h>
-#else
-#pragma message "Usage of zlib is DISABLED!"
+#ifdef HAVE_ZLIB
+ #include <zlib.h>
+#endif
+#ifdef HAVE_BZ2
+ #include <bzlib.h>
#endif
#ifdef WORDS_BIGENDIAN
@@ -65,19 +62,50 @@ using namespace std;
class FileFdPrivate {
public:
-#if APT_USE_ZLIB
+#ifdef HAVE_ZLIB
gzFile gz;
#else
void* gz;
#endif
+#ifdef HAVE_BZ2
+ BZFILE* bz2;
+#else
+ void* bz2;
+#endif
int compressed_fd;
pid_t compressor_pid;
bool pipe;
APT::Configuration::Compressor compressor;
unsigned int openmode;
unsigned long long seekpos;
- FileFdPrivate() : gz(NULL), compressed_fd(-1), compressor_pid(-1), pipe(false),
+ FileFdPrivate() : gz(NULL), bz2(NULL),
+ compressed_fd(-1), compressor_pid(-1), pipe(false),
openmode(0), seekpos(0) {};
+ bool CloseDown(std::string const &FileName)
+ {
+ bool Res = true;
+#ifdef HAVE_ZLIB
+ if (gz != NULL) {
+ int const e = gzclose(gz);
+ gz = NULL;
+ // gzdclose() on empty files always fails with "buffer error" here, ignore that
+ if (e != 0 && e != Z_BUF_ERROR)
+ Res &= _error->Errno("close",_("Problem closing the gzip file %s"), FileName.c_str());
+ }
+#endif
+#ifdef HAVE_BZ2
+ if (bz2 != NULL) {
+ BZ2_bzclose(bz2);
+ bz2 = NULL;
+ }
+#endif
+ if (compressor_pid > 0)
+ ExecWait(compressor_pid, "FileFdCompressor", true);
+ compressor_pid = -1;
+
+ return Res;
+ }
+ ~FileFdPrivate() { CloseDown(""); }
};
// RunScripts - Run a set of scripts from a configuration subtree /*{{{*/
@@ -387,6 +415,13 @@ std::vector<string> GetListOfFilesInDir(string const &Dir, std::vector<string> c
{
if (RealFileExists(File.c_str()) == false)
{
+ // do not show ignoration warnings for directories
+ if (
+#ifdef _DIRENT_HAVE_D_TYPE
+ Ent->d_type == DT_DIR ||
+#endif
+ DirectoryExists(File.c_str()) == true)
+ continue;
if (SilentIgnore.Match(Ent->d_name) == false)
_error->Notice(_("Ignoring '%s' in directory '%s' as it is not a regular file"), Ent->d_name, Dir.c_str());
continue;
@@ -458,6 +493,80 @@ std::vector<string> GetListOfFilesInDir(string const &Dir, std::vector<string> c
std::sort(List.begin(),List.end());
return List;
}
+std::vector<string> GetListOfFilesInDir(string const &Dir, bool SortList)
+{
+ bool const Debug = _config->FindB("Debug::GetListOfFilesInDir", false);
+ if (Debug == true)
+ std::clog << "Accept in " << Dir << " all regular files" << std::endl;
+
+ std::vector<string> List;
+
+ if (DirectoryExists(Dir.c_str()) == false)
+ {
+ _error->Error(_("List of files can't be created as '%s' is not a directory"), Dir.c_str());
+ return List;
+ }
+
+ DIR *D = opendir(Dir.c_str());
+ if (D == 0)
+ {
+ _error->Errno("opendir",_("Unable to read %s"),Dir.c_str());
+ return List;
+ }
+
+ for (struct dirent *Ent = readdir(D); Ent != 0; Ent = readdir(D))
+ {
+ // skip "hidden" files
+ if (Ent->d_name[0] == '.')
+ continue;
+
+ // Make sure it is a file and not something else
+ string const File = flCombine(Dir,Ent->d_name);
+#ifdef _DIRENT_HAVE_D_TYPE
+ if (Ent->d_type != DT_REG)
+#endif
+ {
+ if (RealFileExists(File.c_str()) == false)
+ {
+ if (Debug == true)
+ std::clog << "Bad file: " << Ent->d_name << " → it is not a real file" << std::endl;
+ continue;
+ }
+ }
+
+ // Skip bad filenames ala run-parts
+ const char *C = Ent->d_name;
+ for (; *C != 0; ++C)
+ if (isalpha(*C) == 0 && isdigit(*C) == 0
+ && *C != '_' && *C != '-' && *C != '.')
+ break;
+
+ // we don't reach the end of the name -> bad character included
+ if (*C != 0)
+ {
+ if (Debug == true)
+ std::clog << "Bad file: " << Ent->d_name << " → bad character »" << *C << "« in filename" << std::endl;
+ continue;
+ }
+
+ // skip filenames which end with a period. These are never valid
+ if (*(C - 1) == '.')
+ {
+ if (Debug == true)
+ std::clog << "Bad file: " << Ent->d_name << " → Period as last character" << std::endl;
+ continue;
+ }
+
+ if (Debug == true)
+ std::clog << "Accept file: " << Ent->d_name << " in " << Dir << std::endl;
+ List.push_back(File);
+ }
+ closedir(D);
+
+ if (SortList == true)
+ std::sort(List.begin(),List.end());
+ return List;
+}
/*}}}*/
// SafeGetCWD - This is a safer getcwd that returns a dynamic string /*{{{*/
// ---------------------------------------------------------------------
@@ -754,7 +863,6 @@ bool FileFd::Open(string FileName,unsigned int const Mode,CompressMode Compress,
if (Compress == Auto && (Mode & WriteOnly) == WriteOnly)
return _error->Error("Autodetection on %s only works in ReadOnly openmode!", FileName.c_str());
- // FIXME: Denote inbuilt compressors somehow - as we don't need to have the binaries for them
std::vector<APT::Configuration::Compressor> const compressors = APT::Configuration::getCompressors();
std::vector<APT::Configuration::Compressor>::const_iterator compressor = compressors.begin();
if (Compress == Auto)
@@ -822,8 +930,6 @@ bool FileFd::Open(string FileName,unsigned int const Mode,CompressMode Compress,
bool FileFd::Open(string FileName,unsigned int const Mode,APT::Configuration::Compressor const &compressor, unsigned long const Perms)
{
Close();
- d = new FileFdPrivate;
- d->openmode = Mode;
Flags = AutoClose;
if ((Mode & WriteOnly) != WriteOnly && (Mode & (Atomic | Create | Empty | Exclusive)) != 0)
@@ -917,8 +1023,6 @@ bool FileFd::OpenDescriptor(int Fd, unsigned int const Mode, CompressMode Compre
bool FileFd::OpenDescriptor(int Fd, unsigned int const Mode, APT::Configuration::Compressor const &compressor, bool AutoClose)
{
Close();
- d = new FileFdPrivate;
- d->openmode = Mode;
Flags = (AutoClose) ? FileFd::AutoClose : 0;
iFd = Fd;
this->FileName = "";
@@ -932,32 +1036,71 @@ bool FileFd::OpenDescriptor(int Fd, unsigned int const Mode, APT::Configuration:
}
bool FileFd::OpenInternDescriptor(unsigned int const Mode, APT::Configuration::Compressor const &compressor)
{
- d->compressor = compressor;
if (compressor.Name == "." || compressor.Binary.empty() == true)
return true;
-#if APT_USE_ZLIB
- else if (compressor.Name == "gzip")
+
+ if (d == NULL)
+ {
+ d = new FileFdPrivate();
+ d->openmode = Mode;
+ d->compressor = compressor;
+ }
+
+#ifdef HAVE_ZLIB
+ if (compressor.Name == "gzip")
{
+ if (d->gz != NULL)
+ {
+ gzclose(d->gz);
+ d->gz = NULL;
+ }
if ((Mode & ReadWrite) == ReadWrite)
d->gz = gzdopen(iFd, "r+");
else if ((Mode & WriteOnly) == WriteOnly)
d->gz = gzdopen(iFd, "w");
else
- d->gz = gzdopen (iFd, "r");
+ d->gz = gzdopen(iFd, "r");
if (d->gz == NULL)
return false;
Flags |= Compressed;
return true;
}
#endif
+#ifdef HAVE_BZ2
+ if (compressor.Name == "bzip2")
+ {
+ if (d->bz2 != NULL)
+ {
+ BZ2_bzclose(d->bz2);
+ d->bz2 = NULL;
+ }
+ if ((Mode & ReadWrite) == ReadWrite)
+ d->bz2 = BZ2_bzdopen(iFd, "r+");
+ else if ((Mode & WriteOnly) == WriteOnly)
+ d->bz2 = BZ2_bzdopen(iFd, "w");
+ else
+ d->bz2 = BZ2_bzdopen(iFd, "r");
+ if (d->bz2 == NULL)
+ return false;
+ Flags |= Compressed;
+ return true;
+ }
+#endif
+
+ // collect zombies here in case we reopen
+ if (d->compressor_pid > 0)
+ ExecWait(d->compressor_pid, "FileFdCompressor", true);
if ((Mode & ReadWrite) == ReadWrite)
+ {
+ Flags |= Fail;
return _error->Error("ReadWrite mode is not supported for file %s", FileName.c_str());
+ }
bool const Comp = (Mode & WriteOnly) == WriteOnly;
- // Handle 'decompression' of empty files
if (Comp == false)
{
+ // Handle 'decompression' of empty files
struct stat Buf;
fstat(iFd, &Buf);
if (Buf.st_size == 0 && S_ISFIFO(Buf.st_mode) == false)
@@ -966,13 +1109,19 @@ bool FileFd::OpenInternDescriptor(unsigned int const Mode, APT::Configuration::C
// We don't need the file open - instead let the compressor open it
// as he properly knows better how to efficiently read from 'his' file
if (FileName.empty() == false)
+ {
close(iFd);
+ iFd = -1;
+ }
}
// Create a data pipe
int Pipe[2] = {-1,-1};
if (pipe(Pipe) != 0)
+ {
+ Flags |= Fail;
return _error->Errno("pipe",_("Failed to create subprocess IPC"));
+ }
for (int J = 0; J != 2; J++)
SetCloseExec(Pipe[J],true);
@@ -999,6 +1148,12 @@ bool FileFd::OpenInternDescriptor(unsigned int const Mode, APT::Configuration::C
dup2(d->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);
@@ -1028,7 +1183,7 @@ bool FileFd::OpenInternDescriptor(unsigned int const Mode, APT::Configuration::C
close(Pipe[0]);
else
close(Pipe[1]);
- if (Comp == true || FileName.empty() == true)
+ if ((Comp == true || FileName.empty() == true) && d->compressed_fd != -1)
close(d->compressed_fd);
return true;
@@ -1041,6 +1196,12 @@ bool FileFd::OpenInternDescriptor(unsigned int const Mode, APT::Configuration::C
FileFd::~FileFd()
{
Close();
+ if (d != NULL)
+ {
+ d->CloseDown(FileName);
+ delete d;
+ d = NULL;
+ }
}
/*}}}*/
// FileFd::Read - Read a bit of the file /*{{{*/
@@ -1056,9 +1217,14 @@ bool FileFd::Read(void *To,unsigned long long Size,unsigned long long *Actual)
*((char *)To) = '\0';
do
{
-#if APT_USE_ZLIB
- if (d->gz != NULL)
- Res = gzread(d->gz,To,Size);
+#ifdef HAVE_ZLIB
+ if (d != NULL && d->gz != NULL)
+ Res = gzread(d->gz,To,Size);
+ else
+#endif
+#ifdef HAVE_BZ2
+ if (d != NULL && d->bz2 != NULL)
+ Res = BZ2_bzread(d->bz2,To,Size);
else
#endif
Res = read(iFd,To,Size);
@@ -1068,8 +1234,8 @@ bool FileFd::Read(void *To,unsigned long long Size,unsigned long long *Actual)
if (errno == EINTR)
continue;
Flags |= Fail;
-#if APT_USE_ZLIB
- if (d->gz != NULL)
+#ifdef HAVE_ZLIB
+ if (d != NULL && d->gz != NULL)
{
int err;
char const * const errmsg = gzerror(d->gz, &err);
@@ -1077,12 +1243,22 @@ bool FileFd::Read(void *To,unsigned long long Size,unsigned long long *Actual)
return _error->Error("gzread: %s (%d: %s)", _("Read error"), err, errmsg);
}
#endif
+#ifdef HAVE_BZ2
+ if (d != NULL && d->bz2 != NULL)
+ {
+ int err;
+ char const * const errmsg = BZ2_bzerror(d->bz2, &err);
+ if (err != BZ_IO_ERROR)
+ return _error->Error("BZ2_bzread: %s (%d: %s)", _("Read error"), err, errmsg);
+ }
+#endif
return _error->Errno("read",_("Read error"));
}
To = (char *)To + Res;
Size -= Res;
- d->seekpos += Res;
+ if (d != NULL)
+ d->seekpos += Res;
if (Actual != 0)
*Actual += Res;
}
@@ -1109,8 +1285,8 @@ bool FileFd::Read(void *To,unsigned long long Size,unsigned long long *Actual)
char* FileFd::ReadLine(char *To, unsigned long long const Size)
{
*To = '\0';
-#if APT_USE_ZLIB
- if (d->gz != NULL)
+#ifdef HAVE_ZLIB
+ if (d != NULL && d->gz != NULL)
return gzgets(d->gz, To, Size);
#endif
@@ -1140,23 +1316,47 @@ bool FileFd::Write(const void *From,unsigned long long Size)
errno = 0;
do
{
-#if APT_USE_ZLIB
- if (d->gz != NULL)
+#ifdef HAVE_ZLIB
+ if (d != NULL && d->gz != NULL)
Res = gzwrite(d->gz,From,Size);
else
#endif
+#ifdef HAVE_BZ2
+ if (d != NULL && d->bz2 != NULL)
+ Res = BZ2_bzwrite(d->bz2,(void*)From,Size);
+ else
+#endif
Res = write(iFd,From,Size);
if (Res < 0 && errno == EINTR)
continue;
if (Res < 0)
{
Flags |= Fail;
+#ifdef HAVE_ZLIB
+ if (d != NULL && d->gz != NULL)
+ {
+ int err;
+ char const * const errmsg = gzerror(d->gz, &err);
+ if (err != Z_ERRNO)
+ return _error->Error("gzwrite: %s (%d: %s)", _("Write error"), err, errmsg);
+ }
+#endif
+#ifdef HAVE_BZ2
+ if (d != NULL && d->bz2 != NULL)
+ {
+ int err;
+ char const * const errmsg = BZ2_bzerror(d->bz2, &err);
+ if (err != BZ_IO_ERROR)
+ return _error->Error("BZ2_bzwrite: %s (%d: %s)", _("Write error"), err, errmsg);
+ }
+#endif
return _error->Errno("write",_("Write error"));
}
From = (char *)From + Res;
Size -= Res;
- d->seekpos += Res;
+ if (d != NULL)
+ d->seekpos += Res;
}
while (Res > 0 && Size > 0);
@@ -1166,13 +1366,39 @@ bool FileFd::Write(const void *From,unsigned long long Size)
Flags |= Fail;
return _error->Error(_("write, still have %llu to write but couldn't"), Size);
}
+bool FileFd::Write(int Fd, const void *From, unsigned long long Size)
+{
+ int Res;
+ errno = 0;
+ do
+ {
+ Res = write(Fd,From,Size);
+ if (Res < 0 && errno == EINTR)
+ continue;
+ if (Res < 0)
+ return _error->Errno("write",_("Write error"));
+
+ From = (char *)From + Res;
+ Size -= Res;
+ }
+ while (Res > 0 && Size > 0);
+
+ if (Size == 0)
+ return true;
+
+ return _error->Error(_("write, still have %llu to write but couldn't"), Size);
+}
/*}}}*/
// FileFd::Seek - Seek in the file /*{{{*/
// ---------------------------------------------------------------------
/* */
bool FileFd::Seek(unsigned long long To)
{
- if (d->pipe == true)
+ if (d != NULL && (d->pipe == true
+#ifdef HAVE_BZ2
+ || d->bz2 != NULL
+#endif
+ ))
{
// Our poor man seeking in pipes is costly, so try to avoid it
unsigned long long seekpos = Tell();
@@ -1182,9 +1408,17 @@ bool FileFd::Seek(unsigned long long To)
return Skip(To - seekpos);
if ((d->openmode & ReadOnly) != ReadOnly)
+ {
+ Flags |= Fail;
return _error->Error("Reopen is only implemented for read-only files!");
- close(iFd);
- iFd = 0;
+ }
+#ifdef HAVE_BZ2
+ if (d->bz2 != NULL)
+ BZ2_bzclose(d->bz2);
+#endif
+ if (iFd != -1)
+ close(iFd);
+ iFd = -1;
if (TemporaryFileName.empty() == false)
iFd = open(TemporaryFileName.c_str(), O_RDONLY);
else if (FileName.empty() == false)
@@ -1194,12 +1428,18 @@ bool FileFd::Seek(unsigned long long To)
if (d->compressed_fd > 0)
if (lseek(d->compressed_fd, 0, SEEK_SET) != 0)
iFd = d->compressed_fd;
- if (iFd <= 0)
+ if (iFd < 0)
+ {
+ Flags |= Fail;
return _error->Error("Reopen is not implemented for pipes opened with FileFd::OpenDescriptor()!");
+ }
}
if (OpenInternDescriptor(d->openmode, d->compressor) == false)
+ {
+ Flags |= Fail;
return _error->Error("Seek on file %s because it couldn't be reopened", FileName.c_str());
+ }
if (To != 0)
return Skip(To);
@@ -1208,8 +1448,8 @@ bool FileFd::Seek(unsigned long long To)
return true;
}
int res;
-#if APT_USE_ZLIB
- if (d->gz)
+#ifdef HAVE_ZLIB
+ if (d != NULL && d->gz)
res = gzseek(d->gz,To,SEEK_SET);
else
#endif
@@ -1220,7 +1460,8 @@ bool FileFd::Seek(unsigned long long To)
return _error->Error("Unable to seek to %llu", To);
}
- d->seekpos = To;
+ if (d != NULL)
+ d->seekpos = To;
return true;
}
/*}}}*/
@@ -1229,7 +1470,11 @@ bool FileFd::Seek(unsigned long long To)
/* */
bool FileFd::Skip(unsigned long long Over)
{
- if (d->pipe == true)
+ if (d != NULL && (d->pipe == true
+#ifdef HAVE_BZ2
+ || d->bz2 != NULL
+#endif
+ ))
{
d->seekpos += Over;
char buffer[1024];
@@ -1237,15 +1482,18 @@ bool FileFd::Skip(unsigned long long Over)
{
unsigned long long toread = std::min((unsigned long long) sizeof(buffer), Over);
if (Read(buffer, toread) == false)
+ {
+ Flags |= Fail;
return _error->Error("Unable to seek ahead %llu",Over);
+ }
Over -= toread;
}
return true;
}
int res;
-#if APT_USE_ZLIB
- if (d->gz != NULL)
+#ifdef HAVE_ZLIB
+ if (d != NULL && d->gz != NULL)
res = gzseek(d->gz,Over,SEEK_CUR);
else
#endif
@@ -1255,7 +1503,8 @@ bool FileFd::Skip(unsigned long long Over)
Flags |= Fail;
return _error->Error("Unable to seek ahead %llu",Over);
}
- d->seekpos = res;
+ if (d != NULL)
+ d->seekpos = res;
return true;
}
@@ -1265,11 +1514,13 @@ bool FileFd::Skip(unsigned long long Over)
/* */
bool FileFd::Truncate(unsigned long long To)
{
- if (d->gz != NULL)
+#if defined HAVE_ZLIB || defined HAVE_BZ2
+ if (d != NULL && (d->gz != NULL || d->bz2 != NULL))
{
Flags |= Fail;
- return _error->Error("Truncating gzipped files is not implemented (%s)", FileName.c_str());
+ return _error->Error("Truncating compressed files is not implemented (%s)", FileName.c_str());
}
+#endif
if (ftruncate(iFd,To) != 0)
{
Flags |= Fail;
@@ -1288,19 +1539,27 @@ unsigned long long FileFd::Tell()
// seeking around, but not all users of FileFd use always Seek() and co
// so d->seekpos isn't always true and we can just use it as a hint if
// we have nothing else, but not always as an authority…
- if (d->pipe == true)
+ if (d != NULL && (d->pipe == true
+#ifdef HAVE_BZ2
+ || d->bz2 != NULL
+#endif
+ ))
return d->seekpos;
off_t Res;
-#if APT_USE_ZLIB
- if (d->gz != NULL)
+#ifdef HAVE_ZLIB
+ if (d != NULL && d->gz != NULL)
Res = gztell(d->gz);
else
#endif
Res = lseek(iFd,0,SEEK_CUR);
if (Res == (off_t)-1)
+ {
+ Flags |= Fail;
_error->Errno("lseek","Failed to determine the current file position");
- d->seekpos = Res;
+ }
+ if (d != NULL)
+ d->seekpos = Res;
return Res;
}
/*}}}*/
@@ -1310,17 +1569,24 @@ unsigned long long FileFd::Tell()
unsigned long long FileFd::FileSize()
{
struct stat Buf;
- if (d->pipe == false && fstat(iFd,&Buf) != 0)
+ if ((d == NULL || d->pipe == false) && fstat(iFd,&Buf) != 0)
+ {
+ Flags |= Fail;
return _error->Errno("fstat","Unable to determine the file size");
+ }
// for compressor pipes st_size is undefined and at 'best' zero
- if (d->pipe == true || S_ISFIFO(Buf.st_mode))
+ if ((d != NULL && d->pipe == true) || S_ISFIFO(Buf.st_mode))
{
// we set it here, too, as we get the info here for free
// in theory the Open-methods should take care of it already
- d->pipe = true;
+ if (d != NULL)
+ d->pipe = true;
if (stat(FileName.c_str(), &Buf) != 0)
+ {
+ Flags |= Fail;
return _error->Errno("stat","Unable to determine the file size");
+ }
}
return Buf.st_size;
@@ -1335,7 +1601,11 @@ unsigned long long FileFd::Size()
// for compressor pipes st_size is undefined and at 'best' zero,
// so we 'read' the content and 'seek' back - see there
- if (d->pipe == true)
+ if (d != NULL && (d->pipe == true
+#ifdef HAVE_BZ2
+ || (d->bz2 && size > 0)
+#endif
+ ))
{
unsigned long long const oldSeek = Tell();
char ignore[1000];
@@ -1346,11 +1616,11 @@ unsigned long long FileFd::Size()
size = Tell();
Seek(oldSeek);
}
-#if APT_USE_ZLIB
+#ifdef HAVE_ZLIB
// only check gzsize if we are actually a gzip file, just checking for
// "gz" is not sufficient as uncompressed files could be opened with
// gzopen in "direct" mode as well
- else if (d->gz && !gzdirect(d->gz) && size > 0)
+ else if (d != NULL && d->gz && !gzdirect(d->gz) && size > 0)
{
off_t const oldPos = lseek(iFd,0,SEEK_CUR);
/* unfortunately zlib.h doesn't provide a gzsize(), so we have to do
@@ -1358,10 +1628,16 @@ unsigned long long FileFd::Size()
* bits of the file */
// FIXME: Size for gz-files is limited by 32bit… no largefile support
if (lseek(iFd, -4, SEEK_END) < 0)
- return _error->Errno("lseek","Unable to seek to end of gzipped file");
+ {
+ Flags |= Fail;
+ return _error->Errno("lseek","Unable to seek to end of gzipped file");
+ }
size = 0L;
if (read(iFd, &size, 4) != 4)
- return _error->Errno("read","Unable to read original size of gzipped file");
+ {
+ Flags |= Fail;
+ return _error->Errno("read","Unable to read original size of gzipped file");
+ }
#ifdef WORDS_BIGENDIAN
uint32_t tmp_size = size;
@@ -1371,7 +1647,10 @@ unsigned long long FileFd::Size()
#endif
if (lseek(iFd, oldPos, SEEK_SET) < 0)
- return _error->Errno("lseek","Unable to seek in gzipped file");
+ {
+ Flags |= Fail;
+ return _error->Errno("lseek","Unable to seek in gzipped file");
+ }
return size;
}
@@ -1386,20 +1665,23 @@ unsigned long long FileFd::Size()
time_t FileFd::ModificationTime()
{
struct stat Buf;
- if (d->pipe == false && fstat(iFd,&Buf) != 0)
+ if ((d == NULL || d->pipe == false) && fstat(iFd,&Buf) != 0)
{
+ Flags |= Fail;
_error->Errno("fstat","Unable to determine the modification time of file %s", FileName.c_str());
return 0;
}
// for compressor pipes st_size is undefined and at 'best' zero
- if (d->pipe == true || S_ISFIFO(Buf.st_mode))
+ if ((d != NULL && d->pipe == true) || S_ISFIFO(Buf.st_mode))
{
// we set it here, too, as we get the info here for free
// in theory the Open-methods should take care of it already
- d->pipe = true;
+ if (d != NULL)
+ d->pipe = true;
if (stat(FileName.c_str(), &Buf) != 0)
{
+ Flags |= Fail;
_error->Errno("fstat","Unable to determine the modification time of file %s", FileName.c_str());
return 0;
}
@@ -1419,16 +1701,15 @@ bool FileFd::Close()
bool Res = true;
if ((Flags & AutoClose) == AutoClose)
{
-#if APT_USE_ZLIB
- if (d != NULL && d->gz != NULL) {
- int const e = gzclose(d->gz);
- // gzdclose() on empty files always fails with "buffer error" here, ignore that
- if (e != 0 && e != Z_BUF_ERROR)
- Res &= _error->Errno("close",_("Problem closing the gzip file %s"), FileName.c_str());
- } else
-#endif
- if (iFd > 0 && close(iFd) != 0)
- Res &= _error->Errno("close",_("Problem closing the file %s"), FileName.c_str());
+ if ((Flags & Compressed) != Compressed && iFd > 0 && close(iFd) != 0)
+ Res &= _error->Errno("close",_("Problem closing the file %s"), FileName.c_str());
+
+ if (d != NULL)
+ {
+ Res &= d->CloseDown(FileName);
+ delete d;
+ d = NULL;
+ }
}
if ((Flags & Replace) == Replace && iFd >= 0) {
@@ -1446,14 +1727,8 @@ bool FileFd::Close()
if (unlink(FileName.c_str()) != 0)
Res &= _error->WarningE("unlnk",_("Problem unlinking the file %s"), FileName.c_str());
- if (d != NULL)
- {
- if (d->compressor_pid > 0)
- ExecWait(d->compressor_pid, "FileFdCompressor", true);
- delete d;
- d = NULL;
- }
-
+ if (Res == false)
+ Flags |= Fail;
return Res;
}
/*}}}*/
@@ -1464,7 +1739,10 @@ bool FileFd::Sync()
{
#ifdef _POSIX_SYNCHRONIZED_IO
if (fsync(iFd) != 0)
+ {
+ Flags |= Fail;
return _error->Errno("sync",_("Problem syncing the file"));
+ }
#endif
return true;
}
diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h
index 3814cfe44..426664d3a 100644
--- a/apt-pkg/contrib/fileutl.h
+++ b/apt-pkg/contrib/fileutl.h
@@ -78,6 +78,7 @@ class FileFd
bool Read(void *To,unsigned long long Size,unsigned long long *Actual = 0);
char* ReadLine(char *To, unsigned long long const Size);
bool Write(const void *From,unsigned long long Size);
+ bool static Write(int Fd, const void *From, unsigned long long Size);
bool Seek(unsigned long long To);
bool Skip(unsigned long long To);
bool Truncate(unsigned long long To);
@@ -171,6 +172,7 @@ std::vector<std::string> GetListOfFilesInDir(std::string const &Dir, std::string
bool const &SortList, bool const &AllowNoExt=false);
std::vector<std::string> GetListOfFilesInDir(std::string const &Dir, std::vector<std::string> const &Ext,
bool const &SortList);
+std::vector<std::string> GetListOfFilesInDir(std::string const &Dir, bool SortList);
std::string SafeGetCWD();
void SetCloseExec(int Fd,bool Close);
void SetNonBlock(int Fd,bool Block);
diff --git a/apt-pkg/contrib/mmap.cc b/apt-pkg/contrib/mmap.cc
index 160718ea5..2d12b6fe9 100644
--- a/apt-pkg/contrib/mmap.cc
+++ b/apt-pkg/contrib/mmap.cc
@@ -84,6 +84,7 @@ bool MMap::Map(FileFd &Fd)
if ((Flags & ReadOnly) != ReadOnly)
return _error->Error("Compressed file %s can only be mapped readonly", Fd.Name().c_str());
Base = new unsigned char[iSize];
+ SyncToFd = new FileFd();
if (Fd.Seek(0L) == false || Fd.Read(Base, iSize) == false)
return _error->Error("Compressed file %s can't be read into mmap", Fd.Name().c_str());
return true;
diff --git a/apt-pkg/contrib/netrc.cc b/apt-pkg/contrib/netrc.cc
index cb7d36088..56e59d84b 100644
--- a/apt-pkg/contrib/netrc.cc
+++ b/apt-pkg/contrib/netrc.cc
@@ -68,8 +68,7 @@ int parsenetrc (char *host, char *login, char *password, char *netrcfile = NULL)
if (!home)
return -1;
- asprintf (&netrcfile, "%s%s%s", home, DIR_CHAR, NETRC);
- if(!netrcfile)
+ if (asprintf (&netrcfile, "%s%s%s", home, DIR_CHAR, NETRC) == -1 || netrcfile == NULL)
return -1;
else
netrc_alloc = true;
diff --git a/apt-pkg/contrib/sha2_internal.cc b/apt-pkg/contrib/sha2_internal.cc
index 6d27e8f2b..83b5a98d3 100644
--- a/apt-pkg/contrib/sha2_internal.cc
+++ b/apt-pkg/contrib/sha2_internal.cc
@@ -552,7 +552,9 @@ void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) {
}
while (len >= SHA256_BLOCK_LENGTH) {
/* Process as many complete blocks as we can */
- SHA256_Transform(context, (sha2_word32*)data);
+ sha2_byte buffer[SHA256_BLOCK_LENGTH];
+ MEMCPY_BCOPY(buffer, data, SHA256_BLOCK_LENGTH);
+ SHA256_Transform(context, (sha2_word32*)buffer);
context->bitcount += SHA256_BLOCK_LENGTH << 3;
len -= SHA256_BLOCK_LENGTH;
data += SHA256_BLOCK_LENGTH;
@@ -879,7 +881,9 @@ void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {
}
while (len >= SHA512_BLOCK_LENGTH) {
/* Process as many complete blocks as we can */
- SHA512_Transform(context, (sha2_word64*)data);
+ sha2_byte buffer[SHA512_BLOCK_LENGTH];
+ MEMCPY_BCOPY(buffer, data, SHA512_BLOCK_LENGTH);
+ SHA512_Transform(context, (sha2_word64*)buffer);
ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
len -= SHA512_BLOCK_LENGTH;
data += SHA512_BLOCK_LENGTH;
diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc
index 861cdcbeb..ca096d736 100644
--- a/apt-pkg/contrib/strutl.cc
+++ b/apt-pkg/contrib/strutl.cc
@@ -23,6 +23,7 @@
#include <ctype.h>
#include <string.h>
+#include <sstream>
#include <stdio.h>
#include <algorithm>
#include <unistd.h>
@@ -910,17 +911,17 @@ bool StrToTime(const string &Val,time_t &Result)
// Handle RFC 1123 time
Month[0] = 0;
- if (sscanf(I," %d %3s %d %d:%d:%d GMT",&Tm.tm_mday,Month,&Tm.tm_year,
+ if (sscanf(I," %2d %3s %4d %2d:%2d:%2d GMT",&Tm.tm_mday,Month,&Tm.tm_year,
&Tm.tm_hour,&Tm.tm_min,&Tm.tm_sec) != 6)
{
// Handle RFC 1036 time
- if (sscanf(I," %d-%3s-%d %d:%d:%d GMT",&Tm.tm_mday,Month,
+ if (sscanf(I," %2d-%3s-%3d %2d:%2d:%2d GMT",&Tm.tm_mday,Month,
&Tm.tm_year,&Tm.tm_hour,&Tm.tm_min,&Tm.tm_sec) == 6)
Tm.tm_year += 1900;
else
{
// asctime format
- if (sscanf(I," %3s %d %d:%d:%d %d",Month,&Tm.tm_mday,
+ if (sscanf(I," %3s %2d %2d:%2d:%2d %4d",Month,&Tm.tm_mday,
&Tm.tm_hour,&Tm.tm_min,&Tm.tm_sec,&Tm.tm_year) != 6)
{
// 'ftp' time
@@ -1168,34 +1169,50 @@ unsigned long RegexChoice(RxChoiceList *Rxs,const char **ListBegin,
return Hits;
}
/*}}}*/
-// ioprintf - C format string outputter to C++ iostreams /*{{{*/
+// {str,io}printf - C format string outputter to C++ strings/iostreams /*{{{*/
// ---------------------------------------------------------------------
/* This is used to make the internationalization strings easier to translate
and to allow reordering of parameters */
-void ioprintf(ostream &out,const char *format,...)
+static bool iovprintf(ostream &out, const char *format,
+ va_list &args, ssize_t &size) {
+ char *S = (char*)malloc(size);
+ ssize_t const n = vsnprintf(S, size, format, args);
+ if (n > -1 && n < size) {
+ out << S;
+ free(S);
+ return true;
+ } else {
+ if (n > -1)
+ size = n + 1;
+ else
+ size *= 2;
+ }
+ free(S);
+ return false;
+}
+void ioprintf(ostream &out,const char *format,...)
{
va_list args;
- va_start(args,format);
-
- // sprintf the description
- char S[4096];
- vsnprintf(S,sizeof(S),format,args);
- out << S;
+ ssize_t size = 400;
+ while (true) {
+ va_start(args,format);
+ if (iovprintf(out, format, args, size) == true)
+ return;
+ va_end(args);
+ }
}
- /*}}}*/
-// strprintf - C format string outputter to C++ strings /*{{{*/
-// ---------------------------------------------------------------------
-/* This is used to make the internationalization strings easier to translate
- and to allow reordering of parameters */
-void strprintf(string &out,const char *format,...)
+void strprintf(string &out,const char *format,...)
{
va_list args;
- va_start(args,format);
-
- // sprintf the description
- char S[4096];
- vsnprintf(S,sizeof(S),format,args);
- out = string(S);
+ ssize_t size = 400;
+ std::ostringstream outstr;
+ while (true) {
+ va_start(args,format);
+ if (iovprintf(outstr, format, args, size) == true)
+ break;
+ va_end(args);
+ }
+ out = outstr.str();
}
/*}}}*/
// safe_snprintf - Safer snprintf /*{{{*/