summaryrefslogtreecommitdiff
path: root/apt-pkg/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg/contrib')
-rw-r--r--apt-pkg/contrib/cmndline.cc8
-rw-r--r--apt-pkg/contrib/configuration.cc149
-rw-r--r--apt-pkg/contrib/configuration.h2
-rw-r--r--apt-pkg/contrib/fileutl.cc425
-rw-r--r--apt-pkg/contrib/fileutl.h7
-rw-r--r--apt-pkg/contrib/mmap.cc52
-rw-r--r--apt-pkg/contrib/netrc.cc54
-rw-r--r--apt-pkg/contrib/netrc.h6
-rw-r--r--apt-pkg/contrib/sha2_internal.cc8
-rw-r--r--apt-pkg/contrib/strutl.cc62
10 files changed, 567 insertions, 206 deletions
diff --git a/apt-pkg/contrib/cmndline.cc b/apt-pkg/contrib/cmndline.cc
index 159f330a1..75d02cad4 100644
--- a/apt-pkg/contrib/cmndline.cc
+++ b/apt-pkg/contrib/cmndline.cc
@@ -92,8 +92,9 @@ bool CommandLine::Parse(int argc,const char **argv)
// Match up to a = against the list
Args *A;
const char *OptEnd = strchrnul(Opt, '=');
- for (A = ArgList; A->end() == false &&
- stringcasecmp(Opt,OptEnd,A->LongOpt) != 0; A++);
+ for (A = ArgList; A->end() == false &&
+ (A->LongOpt == 0 || stringcasecmp(Opt,OptEnd,A->LongOpt) != 0);
+ ++A);
// Failed, look for a word after the first - (no-foo)
bool PreceedMatch = false;
@@ -105,7 +106,8 @@ bool CommandLine::Parse(int argc,const char **argv)
Opt++;
for (A = ArgList; A->end() == false &&
- stringcasecmp(Opt,OptEnd,A->LongOpt) != 0; A++);
+ (A->LongOpt == 0 || stringcasecmp(Opt,OptEnd,A->LongOpt) != 0);
+ ++A);
// Failed again..
if (A->end() == true && OptEnd - Opt != 1)
diff --git a/apt-pkg/contrib/configuration.cc b/apt-pkg/contrib/configuration.cc
index 95c7cb96e..d5334ae72 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;
}
/*}}}*/
@@ -494,24 +511,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 d9c6a30b5..8e09ea0a6 100644
--- a/apt-pkg/contrib/configuration.h
+++ b/apt-pkg/contrib/configuration.h
@@ -104,6 +104,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 1808489d7..a31a8a141 100644
--- a/apt-pkg/contrib/fileutl.cc
+++ b/apt-pkg/contrib/fileutl.cc
@@ -41,17 +41,16 @@
#include <dirent.h>
#include <signal.h>
#include <errno.h>
+#include <glob.h>
+
#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 +64,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 /*{{{*/
@@ -824,6 +854,26 @@ bool ExecWait(pid_t Pid,const char *Name,bool Reap)
}
/*}}}*/
+// StartsWithGPGClearTextSignature - Check if a file is Pgp/GPG clearsigned /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool StartsWithGPGClearTextSignature(string const &FileName)
+{
+ static const char* SIGMSG = "-----BEGIN PGP SIGNED MESSAGE-----\n";
+ char buffer[strlen(SIGMSG)+1];
+ FILE* gpg = fopen(FileName.c_str(), "r");
+ if (gpg == NULL)
+ return false;
+
+ char const * const test = fgets(buffer, sizeof(buffer), gpg);
+ fclose(gpg);
+ if (test == NULL || strcmp(buffer, SIGMSG) != 0)
+ return false;
+
+ return true;
+}
+
+
// FileFd::Open - Open a file /*{{{*/
// ---------------------------------------------------------------------
/* The most commonly used open mode combinations are given with Mode */
@@ -835,7 +885,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)
@@ -903,8 +952,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)
@@ -998,10 +1045,21 @@ 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;
+ if (AutoClose == false && (
+#ifdef HAVE_ZLIB
+ compressor.Name == "gzip" ||
+#endif
+#ifdef HAVE_BZ2
+ compressor.Name == "bzip2" ||
+#endif
+ false))
+ {
+ // Need to duplicate fd here or gzclose for cleanup will close the fd as well
+ iFd = dup(Fd);
+ }
+ else
+ iFd = Fd;
this->FileName = "";
if (OpenInternDescriptor(Mode, compressor) == false)
{
@@ -1013,32 +1071,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)
@@ -1047,13 +1144,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);
@@ -1080,6 +1183,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);
@@ -1109,8 +1218,6 @@ bool FileFd::OpenInternDescriptor(unsigned int const Mode, APT::Configuration::C
close(Pipe[0]);
else
close(Pipe[1]);
- if (Comp == true || FileName.empty() == true)
- close(d->compressed_fd);
return true;
}
@@ -1122,6 +1229,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 /*{{{*/
@@ -1137,9 +1250,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);
@@ -1149,8 +1267,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);
@@ -1158,12 +1276,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;
}
@@ -1190,8 +1318,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
@@ -1221,23 +1349,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);
@@ -1247,13 +1399,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();
@@ -1263,9 +1441,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)
@@ -1275,12 +1461,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);
@@ -1289,8 +1481,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
@@ -1301,7 +1493,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;
}
/*}}}*/
@@ -1310,7 +1503,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];
@@ -1318,15 +1515,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
@@ -1336,7 +1536,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;
}
@@ -1346,11 +1547,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;
@@ -1369,19 +1572,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;
}
/*}}}*/
@@ -1391,17 +1602,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;
@@ -1416,7 +1634,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];
@@ -1427,11 +1649,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
@@ -1439,10 +1661,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;
@@ -1452,7 +1680,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;
}
@@ -1467,20 +1698,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;
}
@@ -1500,19 +1734,18 @@ 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) {
+ if ((Flags & Replace) == Replace) {
if (rename(TemporaryFileName.c_str(), FileName.c_str()) != 0)
Res &= _error->Errno("rename",_("Problem renaming the file %s to %s"), TemporaryFileName.c_str(), FileName.c_str());
@@ -1527,14 +1760,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;
}
/*}}}*/
@@ -1543,12 +1770,42 @@ bool FileFd::Close()
/* */
bool FileFd::Sync()
{
-#ifdef _POSIX_SYNCHRONIZED_IO
if (fsync(iFd) != 0)
+ {
+ Flags |= Fail;
return _error->Errno("sync",_("Problem syncing the file"));
-#endif
+ }
return true;
}
/*}}}*/
gzFile FileFd::gzFd() { return (gzFile) d->gz; }
+
+
+// Glob - wrapper around "glob()" /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+std::vector<std::string> Glob(std::string const &pattern, int flags)
+{
+ std::vector<std::string> result;
+ glob_t globbuf;
+ int glob_res, i;
+
+ glob_res = glob(pattern.c_str(), flags, NULL, &globbuf);
+
+ if (glob_res != 0)
+ {
+ if(glob_res != GLOB_NOMATCH) {
+ _error->Errno("glob", "Problem with glob");
+ return result;
+ }
+ }
+
+ // append results
+ for(i=0;i<globbuf.gl_pathc;i++)
+ result.push_back(string(globbuf.gl_pathv[i]));
+
+ globfree(&globbuf);
+ return result;
+}
+ /*}}}*/
diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h
index 1ca41cb7d..4d933a307 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);
@@ -179,6 +180,9 @@ bool WaitFd(int Fd,bool write = false,unsigned long timeout = 0);
pid_t ExecFork();
bool ExecWait(pid_t Pid,const char *Name,bool Reap = false);
+// check if the given file starts with a PGP cleartext signature
+bool StartsWithGPGClearTextSignature(std::string const &FileName);
+
// File string manipulators
std::string flNotDir(std::string File);
std::string flNotFile(std::string File);
@@ -186,4 +190,7 @@ std::string flNoLink(std::string File);
std::string flExtension(std::string File);
std::string flCombine(std::string Dir,std::string File);
+// simple c++ glob
+std::vector<std::string> Glob(std::string const &pattern, int flags=0);
+
#endif
diff --git a/apt-pkg/contrib/mmap.cc b/apt-pkg/contrib/mmap.cc
index 160718ea5..a176da636 100644
--- a/apt-pkg/contrib/mmap.cc
+++ b/apt-pkg/contrib/mmap.cc
@@ -83,24 +83,26 @@ 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];
+ Base = malloc(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;
}
// Map it.
- Base = mmap(0,iSize,Prot,Map,Fd.Fd(),0);
+ Base = (Flags & Fallback) ? MAP_FAILED : mmap(0,iSize,Prot,Map,Fd.Fd(),0);
if (Base == (void *)-1)
{
- if (errno == ENODEV || errno == EINVAL)
+ if (errno == ENODEV || errno == EINVAL || (Flags & Fallback))
{
// The filesystem doesn't support this particular kind of mmap.
// So we allocate a buffer and read the whole file into it.
if ((Flags & ReadOnly) == ReadOnly)
{
// for readonly, we don't need sync, so make it simple
- Base = new unsigned char[iSize];
+ Base = malloc(iSize);
+ SyncToFd = new FileFd();
return Fd.Read(Base, iSize);
}
// FIXME: Writing to compressed fd's ?
@@ -108,7 +110,7 @@ bool MMap::Map(FileFd &Fd)
if (dupped_fd == -1)
return _error->Errno("mmap", _("Couldn't duplicate file descriptor %i"), Fd.Fd());
- Base = new unsigned char[iSize];
+ Base = calloc(iSize, 1);
SyncToFd = new FileFd (dupped_fd);
if (!SyncToFd->Seek(0L) || !SyncToFd->Read(Base, iSize))
return false;
@@ -134,7 +136,7 @@ bool MMap::Close(bool DoSync)
if (SyncToFd != NULL)
{
- delete[] (char *)Base;
+ free(Base);
delete SyncToFd;
SyncToFd = NULL;
}
@@ -154,11 +156,10 @@ bool MMap::Close(bool DoSync)
/* This is done in syncronous mode - the docs indicate that this will
not return till all IO is complete */
bool MMap::Sync()
-{
+{
if ((Flags & UnMapped) == UnMapped)
return true;
-
-#ifdef _POSIX_SYNCHRONIZED_IO
+
if ((Flags & ReadOnly) != ReadOnly)
{
if (SyncToFd != NULL)
@@ -168,11 +169,12 @@ bool MMap::Sync()
}
else
{
+#ifdef _POSIX_SYNCHRONIZED_IO
if (msync((char *)Base, iSize, MS_SYNC) < 0)
return _error->Errno("msync", _("Unable to synchronize mmap"));
+#endif
}
}
-#endif
return true;
}
/*}}}*/
@@ -183,9 +185,7 @@ bool MMap::Sync(unsigned long Start,unsigned long Stop)
{
if ((Flags & UnMapped) == UnMapped)
return true;
-
-#ifdef _POSIX_SYNCHRONIZED_IO
- unsigned long long PSize = sysconf(_SC_PAGESIZE);
+
if ((Flags & ReadOnly) != ReadOnly)
{
if (SyncToFd != 0)
@@ -196,11 +196,13 @@ bool MMap::Sync(unsigned long Start,unsigned long Stop)
}
else
{
+#ifdef _POSIX_SYNCHRONIZED_IO
+ unsigned long long const PSize = sysconf(_SC_PAGESIZE);
if (msync((char *)Base+(unsigned long long)(Start/PSize)*PSize,Stop - Start,MS_SYNC) < 0)
return _error->Errno("msync", _("Unable to synchronize mmap"));
+#endif
}
}
-#endif
return true;
}
/*}}}*/
@@ -215,7 +217,17 @@ DynamicMMap::DynamicMMap(FileFd &F,unsigned long Flags,unsigned long const &Work
{
if (_error->PendingError() == true)
return;
-
+
+ // disable Moveable if we don't grow
+ if (Grow == 0)
+ this->Flags &= ~Moveable;
+
+#ifndef __linux__
+ // kfreebsd doesn't have mremap, so we use the fallback
+ if ((this->Flags & Moveable) == Moveable)
+ this->Flags |= Fallback;
+#endif
+
unsigned long long EndOfFile = Fd->Size();
if (EndOfFile > WorkSpace)
WorkSpace = EndOfFile;
@@ -282,8 +294,7 @@ DynamicMMap::DynamicMMap(unsigned long Flags,unsigned long const &WorkSpace,
}
#endif
// fallback to a static allocated space
- Base = new unsigned char[WorkSpace];
- memset(Base,0,WorkSpace);
+ Base = calloc(WorkSpace, 1);
iSize = 0;
}
/*}}}*/
@@ -299,7 +310,7 @@ DynamicMMap::~DynamicMMap()
#ifdef _POSIX_MAPPED_FILES
munmap(Base, WorkSpace);
#else
- delete [] (unsigned char *)Base;
+ free(Base);
#endif
return;
}
@@ -328,7 +339,7 @@ unsigned long DynamicMMap::RawAllocate(unsigned long long Size,unsigned long Aln
if(!Grow())
{
_error->Fatal(_("Dynamic MMap ran out of room. Please increase the size "
- "of APT::Cache-Limit. Current value: %lu. (man 5 apt.conf)"), WorkSpace);
+ "of APT::Cache-Start. Current value: %lu. (man 5 apt.conf)"), WorkSpace);
return 0;
}
}
@@ -463,6 +474,9 @@ bool DynamicMMap::Grow() {
Base = realloc(Base, newSize);
if (Base == NULL)
return false;
+ else
+ /* Set new memory to 0 */
+ memset((char*)Base + WorkSpace, 0, newSize - WorkSpace);
}
Pools =(Pool*) Base + poolOffset;
diff --git a/apt-pkg/contrib/netrc.cc b/apt-pkg/contrib/netrc.cc
index 06059dfc1..b3d30fd4a 100644
--- a/apt-pkg/contrib/netrc.cc
+++ b/apt-pkg/contrib/netrc.cc
@@ -45,11 +45,11 @@ enum {
#define NETRC DOT_CHAR "netrc"
/* returns -1 on failure, 0 if the host is found, 1 is the host isn't found */
-int parsenetrc (char *host, char *login, char *password, char *netrcfile = NULL)
+static int parsenetrc_string (char *host, std::string &login, std::string &password, char *netrcfile = NULL)
{
FILE *file;
int retcode = 1;
- int specific_login = (login[0] != 0);
+ int specific_login = (login.empty() == false);
char *home = NULL;
bool netrc_alloc = false;
@@ -69,8 +69,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;
@@ -81,16 +80,17 @@ int parsenetrc (char *host, char *login, char *password, char *netrcfile = NULL)
char *tok;
char *tok_buf;
bool done = false;
- char netrcbuffer[256];
+ char *netrcbuffer = NULL;
+ size_t netrcbuffer_size = 0;
int state = NOTHING;
char state_login = 0; /* Found a login keyword */
char state_password = 0; /* Found a password keyword */
- while (!done && fgets(netrcbuffer, sizeof (netrcbuffer), file)) {
+ while (!done && getline(&netrcbuffer, &netrcbuffer_size, file) != -1) {
tok = strtok_r (netrcbuffer, " \t\n", &tok_buf);
while (!done && tok) {
- if(login[0] && password[0]) {
+ if(login.empty() == false && password.empty() == false) {
done = true;
break;
}
@@ -122,23 +122,13 @@ int parsenetrc (char *host, char *login, char *password, char *netrcfile = NULL)
/* we are now parsing sub-keywords concerning "our" host */
if (state_login) {
if (specific_login)
- state_our_login = !strcasecmp (login, tok);
+ state_our_login = !strcasecmp (login.c_str(), tok);
else
- {
- if (strlen(tok) > LOGINSIZE)
- _error->Error("login token too long %i (max: %i)",
- strlen(tok), LOGINSIZE);
- strncpy (login, tok, LOGINSIZE - 1);
- }
+ login = tok;
state_login = 0;
} else if (state_password) {
- if (state_our_login || !specific_login)
- {
- if (strlen(tok) > PASSWORDSIZE)
- _error->Error("password token too long %i (max %i)",
- strlen(tok), PASSWORDSIZE);
- strncpy (password, tok, PASSWORDSIZE - 1);
- }
+ if (state_our_login || !specific_login)
+ password = tok;
state_password = 0;
} else if (!strcasecmp ("login", tok))
state_login = 1;
@@ -154,8 +144,9 @@ int parsenetrc (char *host, char *login, char *password, char *netrcfile = NULL)
tok = strtok_r (NULL, " \t\n", &tok_buf);
} /* while(tok) */
- } /* while fgets() */
+ } /* while getline() */
+ free(netrcbuffer);
fclose(file);
}
@@ -174,21 +165,20 @@ void maybe_add_auth (URI &Uri, string NetRCFile)
{
if (NetRCFile.empty () == false)
{
- char login[LOGINSIZE] = "";
- char password[PASSWORDSIZE] = "";
+ std::string login, password;
char *netrcfile = strdup(NetRCFile.c_str());
// first check for a generic host based netrc entry
char *host = strdup(Uri.Host.c_str());
- if (host && parsenetrc (host, login, password, netrcfile) == 0)
+ if (host && parsenetrc_string(host, login, password, netrcfile) == 0)
{
if (_config->FindB("Debug::Acquire::netrc", false) == true)
std::clog << "host: " << host
<< " user: " << login
- << " pass-size: " << strlen(password)
+ << " pass-size: " << password.size()
<< std::endl;
- Uri.User = string (login);
- Uri.Password = string (password);
+ Uri.User = login;
+ Uri.Password = password;
free(netrcfile);
free(host);
return;
@@ -199,15 +189,15 @@ void maybe_add_auth (URI &Uri, string NetRCFile)
// a lookup uri.startswith(host) in the netrc file parser (because
// of the "/"
char *hostpath = strdup(string(Uri.Host+Uri.Path).c_str());
- if (hostpath && parsenetrc (hostpath, login, password, netrcfile) == 0)
+ if (hostpath && parsenetrc_string(hostpath, login, password, netrcfile) == 0)
{
if (_config->FindB("Debug::Acquire::netrc", false) == true)
std::clog << "hostpath: " << hostpath
<< " user: " << login
- << " pass-size: " << strlen(password)
+ << " pass-size: " << password.size()
<< std::endl;
- Uri.User = string (login);
- Uri.Password = string (password);
+ Uri.User = login;
+ Uri.Password = password;
}
free(netrcfile);
free(hostpath);
diff --git a/apt-pkg/contrib/netrc.h b/apt-pkg/contrib/netrc.h
index 5931d4a42..7349126c4 100644
--- a/apt-pkg/contrib/netrc.h
+++ b/apt-pkg/contrib/netrc.h
@@ -25,11 +25,5 @@
class URI;
-// Assume: password[0]=0, host[0] != 0.
-// If login[0] = 0, search for login and password within a machine section
-// in the netrc.
-// If login[0] != 0, search for password within machine and login.
-int parsenetrc (char *host, char *login, char *password, char *filename);
-
void maybe_add_auth (URI &Uri, std::string NetRCFile);
#endif
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 99efa8d98..df11a80ad 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>
@@ -751,7 +752,8 @@ bool ReadMessages(int Fd, vector<string> &List)
// Look for the end of the message
for (char *I = Buffer; I + 1 < End; I++)
{
- if (I[0] != '\n' || I[1] != '\n')
+ if (I[1] != '\n' ||
+ (strncmp(I, "\n\n", 2) != 0 && strncmp(I, "\r\n\r\n", 4) != 0))
continue;
// Pull the message out
@@ -759,7 +761,7 @@ bool ReadMessages(int Fd, vector<string> &List)
PartialMessage += Message;
// Fix up the buffer
- for (; I < End && *I == '\n'; I++);
+ for (; I < End && (*I == '\r' || *I == '\n'); ++I);
End -= I-Buffer;
memmove(Buffer,I,End-Buffer);
I = Buffer;
@@ -1168,34 +1170,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 /*{{{*/