Skip to content

Commit

Permalink
archive-tar: turn write_tar_entry into blob-writing only
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Nguyễn Thái Ngọc Duy authored and Junio C Hamano committed May 3, 2012
1 parent 6163cd8 commit d240d41
Showing 1 changed file with 52 additions and 26 deletions.
78 changes: 52 additions & 26 deletions archive-tar.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand Down

0 comments on commit d240d41

Please sign in to comment.