summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--debian/changelog1
-rw-r--r--lib/tarfn.c16
-rw-r--r--lib/tarfn.h8
4 files changed, 33 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index f29e33dd0..03fc9a43a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
2009-02-27 Guillem Jover <guillem@debian.org>
+ * lib/tarfn.h (enum tar_format): New type.
+ (struct TarInfo): Add new format member.
+ * lib/tarfn.c (TAR_MAGIC_USTAR, TAR_MAGIC_GNU): New macros.
+ (struct TarHeader): Add new Prefix member.
+ (DecodeTarHeader): Detect tar formats based on the magic values.
+ Abort on tar_format_ustar and an non-empty Prefix.
+
+2009-02-27 Guillem Jover <guillem@debian.org>
+
* lib/fields.c (f_boolean): Use PKGPFIELD to assign to the correct
member instead of hardcoding to the essential member.
diff --git a/debian/changelog b/debian/changelog
index 1536e0e78..e61d1655f 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -61,6 +61,7 @@ dpkg (1.15.0) UNRELEASED; urgency=low
* Add new option --iosched to start-stop-daemon to be able to set the
IO scheduling class and priority. Closes: #443535
Thanks to Chris Coulson <chrisccoulson@googlemail.com>.
+ * Add tar format detection support to the internal extractor.
[ Raphael Hertzog ]
* Enhance dpkg-shlibdeps's error message when a library can't be found to
diff --git a/lib/tarfn.c b/lib/tarfn.c
index bdf0bb0c1..ecb5acb21 100644
--- a/lib/tarfn.c
+++ b/lib/tarfn.c
@@ -18,6 +18,9 @@
#include <dpkg.h>
#include <dpkg-priv.h>
+#define TAR_MAGIC_USTAR "ustar\0" "00"
+#define TAR_MAGIC_GNU "ustar " " \0"
+
struct TarHeader {
char Name[100];
char Mode[8];
@@ -33,6 +36,7 @@ struct TarHeader {
char GroupName[32];
char MajorDevice[8];
char MinorDevice[8];
+ char Prefix[155]; /* Only valid on ustar. */
};
typedef struct TarHeader TarHeader;
@@ -81,12 +85,22 @@ DecodeTarHeader(char * block, TarInfo * d)
long sum;
long checksum;
+ if (memcmp(h->MagicNumber, TAR_MAGIC_GNU, 6) == 0)
+ d->format = tar_format_gnu;
+ else if (memcmp(h->MagicNumber, TAR_MAGIC_USTAR, 6) == 0)
+ d->format = tar_format_ustar;
+ else
+ d->format = tar_format_old;
+
if ( *h->UserName )
passwd = getpwnam(h->UserName);
if ( *h->GroupName )
group = getgrnam(h->GroupName);
- d->Name = StoC(h->Name, sizeof(h->Name));
+ if (d->format == tar_format_ustar && h->Prefix[0] != '\0')
+ abort();
+ else
+ d->Name = StoC(h->Name, sizeof(h->Name));
d->LinkName = StoC(h->LinkName, sizeof(h->LinkName));
d->Mode = (mode_t)OtoL(h->Mode, sizeof(h->Mode));
d->Size = (size_t)OtoL(h->Size, sizeof(h->Size));
diff --git a/lib/tarfn.h b/lib/tarfn.h
index 4bd0e00f4..469d47699 100644
--- a/lib/tarfn.h
+++ b/lib/tarfn.h
@@ -12,6 +12,13 @@
#include <unistd.h>
#include <sys/types.h>
+enum tar_format {
+ tar_format_old,
+ tar_format_gnu,
+ tar_format_ustar,
+ tar_format_pax,
+};
+
enum TarFileType {
NormalFile0 = '\0', /* For compatibility with decades-old bug */
NormalFile1 = '0',
@@ -27,6 +34,7 @@ enum TarFileType {
typedef enum TarFileType TarFileType;
struct TarInfo {
+ enum tar_format format; /* Tar archive format. */
void * UserData; /* User passed this in as argument */
char * Name; /* File name */
mode_t Mode; /* Unix mode, including device bits. */