archive-tar: turn write_tar_entry into blob-writing only
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>
Thu, 3 May 2012 01:51:01 +0000 (08:51 +0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 3 May 2012 17:22:56 +0000 (10:22 -0700)
Before this patch write_tar_entry() can:

 - write global header
   by write_global_extended_header() calling write_tar_entry with
   with both sha1 and path == NULL

 - write extended header for symlinks, by write_tar_entry() calling
   itself with sha1 != NULL and path == NULL

 - write a normal blob. In this case both sha1 and path are valid.

After this patch, the first two call sites are modified to write the
header without calling write_tar_entry(). The function is now for
writing blobs only. This simplifies handling when write_tar_entry()
learns about large blobs.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
archive-tar.c

index 20af0051a334a1357b055ea10d74f5380117ab68..1727ab90ae1e9fd9584681de956038e34715b135 100644 (file)
@@ -123,6 +123,43 @@ static size_t get_path_prefix(const char *path, size_t pathlen, size_t maxlen)
        return i;
 }
 
+static void prepare_header(struct archiver_args *args,
+                          struct ustar_header *header,
+                          unsigned int mode, unsigned long size)
+{
+       sprintf(header->mode, "%07o", mode & 07777);
+       sprintf(header->size, "%011lo", S_ISREG(mode) ? size : 0);
+       sprintf(header->mtime, "%011lo", (unsigned long) args->time);
+
+       sprintf(header->uid, "%07o", 0);
+       sprintf(header->gid, "%07o", 0);
+       strlcpy(header->uname, "root", sizeof(header->uname));
+       strlcpy(header->gname, "root", sizeof(header->gname));
+       sprintf(header->devmajor, "%07o", 0);
+       sprintf(header->devminor, "%07o", 0);
+
+       memcpy(header->magic, "ustar", 6);
+       memcpy(header->version, "00", 2);
+
+       sprintf(header->chksum, "%07o", ustar_header_chksum(header));
+}
+
+static int write_extended_header(struct archiver_args *args,
+                                const unsigned char *sha1,
+                                const void *buffer, unsigned long size)
+{
+       struct ustar_header header;
+       unsigned int mode;
+       memset(&header, 0, sizeof(header));
+       *header.typeflag = TYPEFLAG_EXT_HEADER;
+       mode = 0100666;
+       sprintf(header.name, "%s.paxheader", sha1_to_hex(sha1));
+       prepare_header(args, &header, mode, size);
+       write_blocked(&header, sizeof(header));
+       write_blocked(buffer, size);
+       return 0;
+}
+
 static int write_tar_entry(struct archiver_args *args,
                const unsigned char *sha1, const char *path, size_t pathlen,
                unsigned int mode, void *buffer, unsigned long size)
@@ -134,13 +171,9 @@ static int write_tar_entry(struct archiver_args *args,
        memset(&header, 0, sizeof(header));
 
        if (!sha1) {
-               *header.typeflag = TYPEFLAG_GLOBAL_HEADER;
-               mode = 0100666;
-               strcpy(header.name, "pax_global_header");
+               die("BUG: sha1 == NULL is not supported");
        } else if (!path) {
-               *header.typeflag = TYPEFLAG_EXT_HEADER;
-               mode = 0100666;
-               sprintf(header.name, "%s.paxheader", sha1_to_hex(sha1));
+               die("BUG: path == NULL is not supported");
        } else {
                if (S_ISDIR(mode) || S_ISGITLINK(mode)) {
                        *header.typeflag = TYPEFLAG_DIR;
@@ -182,25 +215,11 @@ static int write_tar_entry(struct archiver_args *args,
                        memcpy(header.linkname, buffer, size);
        }
 
-       sprintf(header.mode, "%07o", mode & 07777);
-       sprintf(header.size, "%011lo", S_ISREG(mode) ? size : 0);
-       sprintf(header.mtime, "%011lo", (unsigned long) args->time);
-
-       sprintf(header.uid, "%07o", 0);
-       sprintf(header.gid, "%07o", 0);
-       strlcpy(header.uname, "root", sizeof(header.uname));
-       strlcpy(header.gname, "root", sizeof(header.gname));
-       sprintf(header.devmajor, "%07o", 0);
-       sprintf(header.devminor, "%07o", 0);
-
-       memcpy(header.magic, "ustar", 6);
-       memcpy(header.version, "00", 2);
-
-       sprintf(header.chksum, "%07o", ustar_header_chksum(&header));
+       prepare_header(args, &header, mode, size);
 
        if (ext_header.len > 0) {
-               err = write_tar_entry(args, sha1, NULL, 0, 0, ext_header.buf,
-                               ext_header.len);
+               err = write_extended_header(args, sha1, ext_header.buf,
+                                           ext_header.len);
                if (err)
                        return err;
        }
@@ -215,11 +234,18 @@ static int write_global_extended_header(struct archiver_args *args)
 {
        const unsigned char *sha1 = args->commit_sha1;
        struct strbuf ext_header = STRBUF_INIT;
-       int err;
+       struct ustar_header header;
+       unsigned int mode;
+       int err = 0;
 
        strbuf_append_ext_header(&ext_header, "comment", sha1_to_hex(sha1), 40);
-       err = write_tar_entry(args, NULL, NULL, 0, 0, ext_header.buf,
-                       ext_header.len);
+       memset(&header, 0, sizeof(header));
+       *header.typeflag = TYPEFLAG_GLOBAL_HEADER;
+       mode = 0100666;
+       strcpy(header.name, "pax_global_header");
+       prepare_header(args, &header, mode, ext_header.len);
+       write_blocked(&header, sizeof(header));
+       write_blocked(ext_header.buf, ext_header.len);
        strbuf_release(&ext_header);
        return err;
 }