The following commit has been merged in the master branch:
commit 22408d0c3dac33a396a451e18f1e8860793928d3
Author: Guillem Jover <[email protected]>
Date:   Fri Feb 27 06:16:03 2009 +0200

    libdpkg: Add tar format detection support
    
    Recognize old tar, GNU tar and ustar formats. Abort on ustar with non
    empty Prefix field, as we don't properly handle the long names yet.
    Failure for PAX archive is already being handled when acting on the
    typeflag.

diff --git a/ChangeLog b/ChangeLog
index f29e33d..03fc9a4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2009-02-27  Guillem Jover  <[email protected]>
 
+       * 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  <[email protected]>
+
        * 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 1536e0e..e61d165 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 <[email protected]>.
+  * 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 bdf0bb0..ecb5acb 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 4bd0e00..469d476 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. */

-- 
dpkg's main repository


-- 
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]

Reply via email to