]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Failing to write a header is not just a "WARN" problem,
authorTim Kientzle <kientzle@gmail.com>
Thu, 15 May 2008 22:11:25 +0000 (18:11 -0400)
committerTim Kientzle <kientzle@gmail.com>
Thu, 15 May 2008 22:11:25 +0000 (18:11 -0400)
it's a "FAILED" operation.  In particular, this fixes a
relatively obscure problem writing ustar archives with bsdtar.
Prior to this, bsdtar would report additional bogus errors
because it kept trying to write the body even after the
header failed.

SVN-Revision: 57

libarchive/archive_write_set_format_ustar.c
libarchive/test/test_ustar_filenames.c

index e7f652d1dc2a2fa5b47629d8dad9a39ad681f838..970fee8db1b2e885ea8fab4ad49cd0dc482ec896 100644 (file)
@@ -195,7 +195,7 @@ static int
 archive_write_ustar_header(struct archive_write *a, struct archive_entry *entry)
 {
        char buff[512];
-       int ret;
+       int ret, ret2;
        struct ustar *ustar;
 
        ustar = (struct ustar *)a->format_data;
@@ -229,15 +229,17 @@ archive_write_ustar_header(struct archive_write *a, struct archive_entry *entry)
        }
 
        ret = __archive_write_format_header_ustar(a, buff, entry, -1, 1);
-       if (ret != ARCHIVE_OK)
-               return (ret);
-       ret = (a->compressor.write)(a, buff, 512);
-       if (ret != ARCHIVE_OK)
+       if (ret < ARCHIVE_WARN)
                return (ret);
+       ret2 = (a->compressor.write)(a, buff, 512);
+       if (ret2 < ARCHIVE_WARN)
+               return (ret2);
+       if (ret2 < ret)
+               ret = ret2;
 
        ustar->entry_bytes_remaining = archive_entry_size(entry);
        ustar->entry_padding = 0x1ff & (-(int64_t)ustar->entry_bytes_remaining);
-       return (ARCHIVE_OK);
+       return (ret);
 }
 
 /*
@@ -293,7 +295,7 @@ __archive_write_format_header_ustar(struct archive_write *a, char h[512],
                        /* No separator. */
                        archive_set_error(&a->archive, ENAMETOOLONG,
                            "Pathname too long");
-                       ret = ARCHIVE_WARN;
+                       ret = ARCHIVE_FAILED;
                } else if (p[1] == '\0') {
                        /*
                         * The only feasible separator is a final '/';
@@ -303,12 +305,12 @@ __archive_write_format_header_ustar(struct archive_write *a, char h[512],
                         */
                        archive_set_error(&a->archive, ENAMETOOLONG,
                            "Pathname too long");
-                       ret = ARCHIVE_WARN;
+                       ret = ARCHIVE_FAILED;
                } else if (p  > pp + USTAR_prefix_size) {
                        /* Prefix is too long. */
                        archive_set_error(&a->archive, ENAMETOOLONG,
                            "Pathname too long");
-                       ret = ARCHIVE_WARN;
+                       ret = ARCHIVE_FAILED;
                } else {
                        /* Copy prefix and remainder to appropriate places */
                        memcpy(h + USTAR_prefix_offset, pp, p - pp);
@@ -326,7 +328,7 @@ __archive_write_format_header_ustar(struct archive_write *a, char h[512],
                if (copy_length > USTAR_linkname_size) {
                        archive_set_error(&a->archive, ENAMETOOLONG,
                            "Link contents too long");
-                       ret = ARCHIVE_WARN;
+                       ret = ARCHIVE_FAILED;
                        copy_length = USTAR_linkname_size;
                }
                memcpy(h + USTAR_linkname_offset, p, copy_length);
@@ -338,7 +340,7 @@ __archive_write_format_header_ustar(struct archive_write *a, char h[512],
                if (copy_length > USTAR_uname_size) {
                        archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
                            "Username too long");
-                       ret = ARCHIVE_WARN;
+                       ret = ARCHIVE_FAILED;
                        copy_length = USTAR_uname_size;
                }
                memcpy(h + USTAR_uname_offset, p, copy_length);
@@ -350,7 +352,7 @@ __archive_write_format_header_ustar(struct archive_write *a, char h[512],
                if (strlen(p) > USTAR_gname_size) {
                        archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
                            "Group name too long");
-                       ret = ARCHIVE_WARN;
+                       ret = ARCHIVE_FAILED;
                        copy_length = USTAR_gname_size;
                }
                memcpy(h + USTAR_gname_offset, p, copy_length);
@@ -358,28 +360,28 @@ __archive_write_format_header_ustar(struct archive_write *a, char h[512],
 
        if (format_number(archive_entry_mode(entry) & 07777, h + USTAR_mode_offset, USTAR_mode_size, USTAR_mode_max_size, strict)) {
                archive_set_error(&a->archive, ERANGE, "Numeric mode too large");
-               ret = ARCHIVE_WARN;
+               ret = ARCHIVE_FAILED;
        }
 
        if (format_number(archive_entry_uid(entry), h + USTAR_uid_offset, USTAR_uid_size, USTAR_uid_max_size, strict)) {
                archive_set_error(&a->archive, ERANGE, "Numeric user ID too large");
-               ret = ARCHIVE_WARN;
+               ret = ARCHIVE_FAILED;
        }
 
        if (format_number(archive_entry_gid(entry), h + USTAR_gid_offset, USTAR_gid_size, USTAR_gid_max_size, strict)) {
                archive_set_error(&a->archive, ERANGE, "Numeric group ID too large");
-               ret = ARCHIVE_WARN;
+               ret = ARCHIVE_FAILED;
        }
 
        if (format_number(archive_entry_size(entry), h + USTAR_size_offset, USTAR_size_size, USTAR_size_max_size, strict)) {
                archive_set_error(&a->archive, ERANGE, "File size out of range");
-               ret = ARCHIVE_WARN;
+               ret = ARCHIVE_FAILED;
        }
 
        if (format_number(archive_entry_mtime(entry), h + USTAR_mtime_offset, USTAR_mtime_size, USTAR_mtime_max_size, strict)) {
                archive_set_error(&a->archive, ERANGE,
                    "File modification time too large");
-               ret = ARCHIVE_WARN;
+               ret = ARCHIVE_FAILED;
        }
 
        if (archive_entry_filetype(entry) == AE_IFBLK
@@ -388,14 +390,14 @@ __archive_write_format_header_ustar(struct archive_write *a, char h[512],
                        USTAR_rdevmajor_size, USTAR_rdevmajor_max_size, strict)) {
                        archive_set_error(&a->archive, ERANGE,
                            "Major device number too large");
-                       ret = ARCHIVE_WARN;
+                       ret = ARCHIVE_FAILED;
                }
 
                if (format_number(archive_entry_rdevminor(entry), h + USTAR_rdevminor_offset,
                        USTAR_rdevminor_size, USTAR_rdevminor_max_size, strict)) {
                        archive_set_error(&a->archive, ERANGE,
                            "Minor device number too large");
-                       ret = ARCHIVE_WARN;
+                       ret = ARCHIVE_FAILED;
                }
        }
 
@@ -415,7 +417,7 @@ __archive_write_format_header_ustar(struct archive_write *a, char h[512],
                        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
                            "tar format cannot archive this (mode=0%lo)",
                            (unsigned long)archive_entry_mode(entry));
-                       ret = ARCHIVE_WARN;
+                       ret = ARCHIVE_FAILED;
                }
        }
 
index ff65c8a2ef6715d6bbe1d0f9fb4d4f16ce4d55f5..88b4b2c4ac46499587a4a86388505c96ae6bd0e4 100644 (file)
@@ -72,7 +72,7 @@ test_filename(const char *prefix, int dlen, int flen)
        archive_entry_set_mode(ae, S_IFREG | 0755);
        failure("dlen=%d, flen=%d", dlen, flen);
        if (flen > 100) {
-               assertEqualIntA(a, ARCHIVE_WARN, archive_write_header(a, ae));
+               assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae));
        } else {
                assertEqualIntA(a, 0, archive_write_header(a, ae));
        }
@@ -86,7 +86,7 @@ test_filename(const char *prefix, int dlen, int flen)
        archive_entry_set_mode(ae, S_IFDIR | 0755);
        failure("dlen=%d, flen=%d", dlen, flen);
        if (flen >= 100) {
-               assertEqualIntA(a, ARCHIVE_WARN, archive_write_header(a, ae));
+               assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae));
        } else {
                assertEqualIntA(a, 0, archive_write_header(a, ae));
        }
@@ -103,7 +103,7 @@ test_filename(const char *prefix, int dlen, int flen)
        archive_entry_set_mode(ae, S_IFDIR | 0755);
        failure("dlen=%d, flen=%d", dlen, flen);
        if (flen >= 100) {
-               assertEqualIntA(a, ARCHIVE_WARN, archive_write_header(a, ae));
+               assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae));
        } else {
                assertEqualIntA(a, 0, archive_write_header(a, ae));
        }