diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | debian/changelog | 1 | ||||
-rw-r--r-- | lib/tarfn.c | 16 | ||||
-rw-r--r-- | lib/tarfn.h | 8 |
4 files changed, 33 insertions, 1 deletions
@@ -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. */ |