summaryrefslogtreecommitdiff
path: root/apt-inst
diff options
context:
space:
mode:
Diffstat (limited to 'apt-inst')
-rw-r--r--apt-inst/contrib/arfile.cc8
-rw-r--r--apt-inst/contrib/extracttar.cc32
-rw-r--r--apt-inst/deb/debfile.cc41
-rw-r--r--apt-inst/deb/debfile.h1
-rw-r--r--apt-inst/dirstream.cc21
-rw-r--r--apt-inst/extract.cc4
-rw-r--r--apt-inst/filelist.cc4
7 files changed, 60 insertions, 51 deletions
diff --git a/apt-inst/contrib/arfile.cc b/apt-inst/contrib/arfile.cc
index d7ee528ba..77dbc55d6 100644
--- a/apt-inst/contrib/arfile.cc
+++ b/apt-inst/contrib/arfile.cc
@@ -6,7 +6,7 @@
AR File - Handle an 'AR' archive
AR Archives have plain text headers at the start of each file
- section. The headers are aligned on a 2 byte boundry.
+ section. The headers are aligned on a 2 byte boundary.
Information about the structure of AR files can be found in ar(5)
on a BSD system, or in the binutils source.
@@ -64,7 +64,7 @@ ARArchive::~ARArchive()
byte plain text header then the file data, another header, data, etc */
bool ARArchive::LoadHeaders()
{
- signed long Left = File.Size();
+ off_t Left = File.Size();
// Check the magic byte
char Magic[8];
@@ -123,7 +123,7 @@ bool ARArchive::LoadHeaders()
}
// Account for the AR header alignment
- unsigned Skip = Memb->Size % 2;
+ off_t Skip = Memb->Size % 2;
// Add it to the list
Memb->Next = List;
@@ -131,7 +131,7 @@ bool ARArchive::LoadHeaders()
Memb->Start = File.Tell();
if (File.Skip(Memb->Size + Skip) == false)
return false;
- if (Left < (signed)(Memb->Size + Skip))
+ if (Left < (off_t)(Memb->Size + Skip))
return _error->Error(_("Archive is too short"));
Left -= Memb->Size + Skip;
}
diff --git a/apt-inst/contrib/extracttar.cc b/apt-inst/contrib/extracttar.cc
index 49ed5db56..41301d1a6 100644
--- a/apt-inst/contrib/extracttar.cc
+++ b/apt-inst/contrib/extracttar.cc
@@ -6,7 +6,7 @@
Extract a Tar - Tar Extractor
Some performance measurements showed that zlib performed quite poorly
- in comparision to a forked gzip process. This tar extractor makes use
+ in comparison to a forked gzip process. This tar extractor makes use
of the fact that dup'd file descriptors have the same seek pointer
and that gzip will not read past the end of a compressed stream,
even if there is more data. We use the dup property to track extraction
@@ -111,6 +111,12 @@ bool ExtractTar::Done(bool Force)
gzip will efficiently ignore the extra bits. */
bool ExtractTar::StartGzip()
{
+ if (DecompressProg.empty())
+ {
+ InFd.OpenDescriptor(File.Fd(), FileFd::ReadOnly, FileFd::None, false);
+ return true;
+ }
+
int Pipes[2];
if (pipe(Pipes) != 0)
return _error->Errno("pipe",_("Failed to create pipes"));
@@ -161,8 +167,8 @@ bool ExtractTar::Go(pkgDirStream &Stream)
return false;
// Loop over all blocks
- string LastLongLink;
- string LastLongName;
+ string LastLongLink, ItemLink;
+ string LastLongName, ItemName;
while (1)
{
bool BadRecord = false;
@@ -208,25 +214,23 @@ bool ExtractTar::Go(pkgDirStream &Stream)
StrToNum(Tar->Major,Itm.Major,sizeof(Tar->Major),8) == false ||
StrToNum(Tar->Minor,Itm.Minor,sizeof(Tar->Minor),8) == false)
return _error->Error(_("Corrupted archive"));
-
- // Grab the filename
+
+ // Grab the filename and link target: use last long name if one was
+ // set, otherwise use the header value as-is, but remember that it may
+ // fill the entire 100-byte block and needs to be zero-terminated.
+ // See Debian Bug #689582.
if (LastLongName.empty() == false)
Itm.Name = (char *)LastLongName.c_str();
else
- {
- Tar->Name[sizeof(Tar->Name)-1] = 0;
- Itm.Name = Tar->Name;
- }
+ Itm.Name = (char *)ItemName.assign(Tar->Name, sizeof(Tar->Name)).c_str();
if (Itm.Name[0] == '.' && Itm.Name[1] == '/' && Itm.Name[2] != 0)
Itm.Name += 2;
-
- // Grab the link target
- Tar->Name[sizeof(Tar->LinkName)-1] = 0;
- Itm.LinkTarget = Tar->LinkName;
if (LastLongLink.empty() == false)
Itm.LinkTarget = (char *)LastLongLink.c_str();
-
+ else
+ Itm.LinkTarget = (char *)ItemLink.assign(Tar->LinkName, sizeof(Tar->LinkName)).c_str();
+
// Convert the type over
switch (Tar->LinkFlag)
{
diff --git a/apt-inst/deb/debfile.cc b/apt-inst/deb/debfile.cc
index ab4037915..a811bbe88 100644
--- a/apt-inst/deb/debfile.cc
+++ b/apt-inst/deb/debfile.cc
@@ -42,17 +42,19 @@ debDebFile::debDebFile(FileFd &File) : File(File), AR(File)
return;
}
- if (!CheckMember("control.tar.gz")) {
- _error->Error(_("This is not a valid DEB archive, missing '%s' member"), "control.tar.gz");
+ if (!CheckMember("control.tar") &&
+ !CheckMember("control.tar.gz") &&
+ !CheckMember("control.tar.xz")) {
+ _error->Error(_("This is not a valid DEB archive, missing '%s' member"), "control.tar");
return;
}
- if (!CheckMember("data.tar.gz") &&
+ if (!CheckMember("data.tar") &&
+ !CheckMember("data.tar.gz") &&
!CheckMember("data.tar.bz2") &&
!CheckMember("data.tar.lzma") &&
!CheckMember("data.tar.xz")) {
- // FIXME: add data.tar.xz here - adding it now would require a Translation round for a very small gain
- _error->Error(_("This is not a valid DEB archive, it has no '%s', '%s' or '%s' member"), "data.tar.gz", "data.tar.bz2", "data.tar.lzma");
+ _error->Error(_("This is not a valid DEB archive, missing '%s' member"), "data.tar");
return;
}
}
@@ -89,21 +91,20 @@ const ARArchive::Member *debDebFile::GotoMember(const char *Name)
return Member;
}
/*}}}*/
-// DebFile::ExtractArchive - Extract the archive data itself /*{{{*/
+// DebFile::ExtractTarMember - Extract the contents of a tar member /*{{{*/
// ---------------------------------------------------------------------
/* Simple wrapper around tar.. */
-bool debDebFile::ExtractArchive(pkgDirStream &Stream)
+bool debDebFile::ExtractTarMember(pkgDirStream &Stream,const char *Name)
{
// Get the archive member
const ARArchive::Member *Member = NULL;
std::string Compressor;
- std::string const data = "data.tar";
std::vector<APT::Configuration::Compressor> compressor = APT::Configuration::getCompressors();
for (std::vector<APT::Configuration::Compressor>::const_iterator c = compressor.begin();
c != compressor.end(); ++c)
{
- Member = AR.FindMember(std::string(data).append(c->Extension).c_str());
+ Member = AR.FindMember(std::string(Name).append(c->Extension).c_str());
if (Member == NULL)
continue;
Compressor = c->Binary;
@@ -111,8 +112,11 @@ bool debDebFile::ExtractArchive(pkgDirStream &Stream)
}
if (Member == NULL)
+ Member = AR.FindMember(std::string(Name).c_str());
+
+ if (Member == NULL)
{
- std::string ext = "data.tar.{";
+ std::string ext = std::string(Name) + ".{";
for (std::vector<APT::Configuration::Compressor>::const_iterator c = compressor.begin();
c != compressor.end(); ++c)
ext.append(c->Extension.substr(1));
@@ -130,6 +134,14 @@ bool debDebFile::ExtractArchive(pkgDirStream &Stream)
return Tar.Go(Stream);
}
/*}}}*/
+// DebFile::ExtractArchive - Extract the archive data itself /*{{{*/
+// ---------------------------------------------------------------------
+/* Simple wrapper around DebFile::ExtractTarMember. */
+bool debDebFile::ExtractArchive(pkgDirStream &Stream)
+{
+ return ExtractTarMember(Stream, "data.tar");
+}
+ /*}}}*/
// DebFile::ControlExtract::DoItem - Control Tar Extraction /*{{{*/
// ---------------------------------------------------------------------
@@ -195,14 +207,7 @@ bool debDebFile::MemControlExtract::Process(Item &Itm,const unsigned char *Data,
it parses it into a tag section parser. */
bool debDebFile::MemControlExtract::Read(debDebFile &Deb)
{
- // Get the archive member and positition the file
- const ARArchive::Member *Member = Deb.GotoMember("control.tar.gz");
- if (Member == 0)
- return false;
-
- // Extract it.
- ExtractTar Tar(Deb.GetFile(),Member->Size,"gzip");
- if (Tar.Go(*this) == false)
+ if (Deb.ExtractTarMember(*this, "control.tar") == false)
return false;
if (Control == 0)
diff --git a/apt-inst/deb/debfile.h b/apt-inst/deb/debfile.h
index 38211fb0f..ecef71d21 100644
--- a/apt-inst/deb/debfile.h
+++ b/apt-inst/deb/debfile.h
@@ -48,6 +48,7 @@ class debDebFile
class ControlExtract;
class MemControlExtract;
+ bool ExtractTarMember(pkgDirStream &Stream, const char *Name);
bool ExtractArchive(pkgDirStream &Stream);
const ARArchive::Member *GotoMember(const char *Name);
inline FileFd &GetFile() {return File;};
diff --git a/apt-inst/dirstream.cc b/apt-inst/dirstream.cc
index 65d1aa188..e06c30a57 100644
--- a/apt-inst/dirstream.cc
+++ b/apt-inst/dirstream.cc
@@ -19,8 +19,8 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <sys/time.h>
#include <errno.h>
-#include <utime.h>
#include <unistd.h>
#include <apti18n.h>
/*}}}*/
@@ -93,19 +93,18 @@ bool pkgDirStream::FinishedFile(Item &Itm,int Fd)
{
if (Fd < 0)
return true;
-
- if (close(Fd) != 0)
- return _error->Errno("close",_("Failed to close file %s"),Itm.Name);
/* Set the modification times. The only way it can fail is if someone
has futzed with our file, which is intolerable :> */
- struct utimbuf Time;
- Time.actime = Itm.MTime;
- Time.modtime = Itm.MTime;
- if (utime(Itm.Name,&Time) != 0)
- _error->Errno("utime",_("Failed to close file %s"),Itm.Name);
-
- return true;
+ struct timeval times[2];
+ times[0].tv_sec = times[1].tv_sec = Itm.MTime;
+ times[0].tv_usec = times[1].tv_usec = 0;
+ if (utimes(Itm.Name, times) != 0)
+ _error->Errno("utimes", "Failed to set modification time for %s",Itm.Name);
+
+ if (close(Fd) != 0)
+ return _error->Errno("close",_("Failed to close file %s"),Itm.Name);
+ return true;
}
/*}}}*/
// DirStream::Fail - Failed processing a file /*{{{*/
diff --git a/apt-inst/extract.cc b/apt-inst/extract.cc
index 2c95fba92..b3dfccfc6 100644
--- a/apt-inst/extract.cc
+++ b/apt-inst/extract.cc
@@ -10,7 +10,7 @@
object is unpacked to '.dpkg.new' then the original is hardlinked to
'.dpkg.tmp' and finally the new object is renamed to overwrite the old
one. From an external perspective the file never ceased to exist.
- After the archive has been sucessfully unpacked the .dpkg.tmp files
+ After the archive has been successfully unpacked the .dpkg.tmp files
are erased. A failure causes all the .dpkg.tmp files to be restored.
Decisions about unpacking go like this:
@@ -22,7 +22,7 @@
[Note, this is reduced to only check if a file was expected to be
there]
- If the existing link/file is not a directory then it is replaced
- irregardless
+ regardless
- If the existing link/directory is being replaced by a directory then
absolutely nothing happens.
- If the existing link/directory is being replaced by a link then
diff --git a/apt-inst/filelist.cc b/apt-inst/filelist.cc
index 879c07855..defc4f4df 100644
--- a/apt-inst/filelist.cc
+++ b/apt-inst/filelist.cc
@@ -5,14 +5,14 @@
File Listing - Manages a Cache of File -> Package names.
- Diversions add some signficant complexity to the system. To keep
+ Diversions add some significant complexity to the system. To keep
storage space down in the very special case of a diverted file no
extra bytes are allocated in the Node structure. Instead a diversion
is inserted directly into the hash table and its flag bit set. Every
lookup for that filename will always return the diversion.
The hash buckets are stored in sorted form, with diversions having
- the higest sort order. Identical files are assigned the same file
+ the highest sort order. Identical files are assigned the same file
pointer, thus after a search all of the nodes owning that file can be
found by iterating down the bucket.