The following commit has been merged in the master branch:
commit 326d7b43ffd8b6c8e1bf4dcd5c5495ee5129631f
Author: Guillem Jover <[email protected]>
Date:   Mon Nov 1 21:41:46 2010 +0100

    libdpkg: Refactor tar_gnu_long() out from tar_extractor()

diff --git a/lib/dpkg/tarfn.c b/lib/dpkg/tarfn.c
index e7bccf7..564b4ee 100644
--- a/lib/dpkg/tarfn.c
+++ b/lib/dpkg/tarfn.c
@@ -228,6 +228,54 @@ tar_header_decode(struct tar_header *h, struct tar_entry 
*d)
        return tar_header_checksum(h);
 }
 
+/**
+ * Decode a GNU longlink or longname from the tar archive.
+ *
+ * The way the GNU long{link,name} stuff works is like this:
+ *
+ * - The first header is a “dummy” header that contains the size of the
+ *   filename.
+ * - The next N headers contain the filename.
+ * - After the headers with the filename comes the “real” header with a
+ *   bogus name or link.
+ */
+static int
+tar_gnu_long(void *ctx, const struct tar_operations *ops, struct tar_entry *te,
+             char **longp)
+{
+       char buf[TARBLKSZ];
+       char *bp;
+       int status = 0;
+       int long_read;
+
+       free(*longp);
+       *longp = bp = m_malloc(te->size);
+
+       for (long_read = te->size; long_read > 0; long_read -= TARBLKSZ) {
+               int copysize;
+
+               status = ops->read(ctx, buf, TARBLKSZ);
+               if (status == TARBLKSZ)
+                       status = 0;
+               else {
+                       /* Read partial header record? */
+                       if (status > 0) {
+                               errno = 0;
+                               status = -1;
+                       }
+
+                       /* If we didn't get TARBLKSZ bytes read, punt. */
+                       break;
+               }
+
+               copysize = min(long_read, TARBLKSZ);
+               memcpy(bp, buf, copysize);
+               bp += copysize;
+       };
+
+       return status;
+}
+
 struct symlinkList {
        struct symlinkList *next;
        struct tar_entry h;
@@ -241,9 +289,6 @@ tar_extractor(void *ctx, const struct tar_operations *ops)
        struct tar_entry h;
 
        char *next_long_name, *next_long_link;
-       char *bp;
-       char **longp;
-       int long_read;
        struct symlinkList *symlink_head, *symlink_tail, *symlink_node;
 
        next_long_name = NULL;
@@ -326,55 +371,10 @@ tar_extractor(void *ctx, const struct tar_operations *ops)
                        status = ops->mknod(ctx, &h);
                        break;
                case tar_filetype_gnu_longlink:
+                       status = tar_gnu_long(ctx, ops, &h, &next_long_link);
+                       break;
                case tar_filetype_gnu_longname:
-                       /* Set longp to the location of the long filename or
-                        * link we're trying to deal with. */
-                       longp = ((h.type == tar_filetype_gnu_longname) ?
-                                &next_long_name :
-                                &next_long_link);
-
-                       if (*longp)
-                               free(*longp);
-
-                       *longp = m_malloc(h.size);
-                       bp = *longp;
-
-                       /* The way the GNU long{link,name} stuff works is like
-                        * this:
-                        *
-                        * The first header is a “dummy” header that contains
-                        *   the size of the filename.
-                        * The next N headers contain the filename.
-                        * After the headers with the filename comes the
-                        *   “real” header with a bogus name or link. */
-                       for (long_read = h.size;
-                            long_read > 0;
-                            long_read -= TARBLKSZ) {
-                               int copysize;
-
-                               status = ops->read(ctx, buffer, TARBLKSZ);
-                               /* If we didn't get TARBLKSZ bytes read, punt. 
*/
-                               if (status != TARBLKSZ) {
-                                        /* Read partial header record? */
-                                       if (status > 0) {
-                                               errno = 0;
-                                               status = -1;
-                                       }
-                                       break;
-                               }
-                               copysize = min(long_read, TARBLKSZ);
-                               memcpy (bp, buffer, copysize);
-                               bp += copysize;
-                       };
-
-                       /* In case of error do not overwrite status with 0. */
-                       if (status < 0)
-                               break;
-
-                       /* This decode function expects status to be 0 after
-                        * the case statement if we successfully decoded. I
-                        * guess what we just did was successful. */
-                       status = 0;
+                       status = tar_gnu_long(ctx, ops, &h, &next_long_name);
                        break;
                default:
                        /* Indicates broken tarfile: “Bad header field”. */

-- 
dpkg's main repository


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

Reply via email to