From 7cb84c25ee51f443c69443e217efe194d12678ea Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Wed, 7 Oct 2009 18:40:07 +0300 Subject: [PATCH] Use file's mtime as mtime for its extended header. This makes two pax archives binary equivalent if they have the same contents and care is taken to make extended headers otherwise reproducible, e.g. by using: --pax-option=exthdr.name=%d/PaxHeaders/%f,atime:=0 Proposed by Michael D. Adams . * src/common.h (start_private_header): Take time_t as 3rd param. (xheader_write): Likewise. * src/create.c (start_private_header): Take time_t as 3rd param. All callers updated. (write_extended): Use file's mtime as mtime for its extended header, Use current time stamp as mtime for global headers. (xheader_write): Take time_t as 3rd param. --- src/common.h | 4 ++-- src/create.c | 25 +++++++++++++------------ src/xheader.c | 6 +++--- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/common.h b/src/common.h index c2a92d2..0020f08 100644 --- a/src/common.h +++ b/src/common.h @@ -452,7 +452,7 @@ void finish_header (struct tar_stat_info *st, union block *header, void simple_finish_header (union block *header); union block * write_extended (bool global, struct tar_stat_info *st, union block *old_header); -union block *start_private_header (const char *name, size_t size); +union block *start_private_header (const char *name, size_t size, time_t t); void write_eot (void); void check_links (void); void exclusion_tag_warning (const char *dirname, const char *tagname, @@ -717,7 +717,7 @@ void xheader_decode_global (struct xheader *xhdr); void xheader_store (char const *keyword, struct tar_stat_info *st, void const *data); void xheader_read (struct xheader *xhdr, union block *header, size_t size); -void xheader_write (char type, char *name, struct xheader *xhdr); +void xheader_write (char type, char *name, time_t t, struct xheader *xhdr); void xheader_write_global (struct xheader *xhdr); void xheader_finish (struct xheader *hdr); void xheader_destroy (struct xheader *hdr); diff --git a/src/create.c b/src/create.c index d4b9ae7..a964bc2 100644 --- a/src/create.c +++ b/src/create.c @@ -515,9 +515,8 @@ write_eot (void) /* Write a "private" header */ union block * -start_private_header (const char *name, size_t size) +start_private_header (const char *name, size_t size, time_t t) { - time_t t; union block *header = find_next_block (); memset (header->buffer, 0, sizeof (union block)); @@ -525,7 +524,6 @@ start_private_header (const char *name, size_t size) tar_name_copy_str (header->header.name, name, NAME_FIELD_SIZE); OFF_TO_CHARS (size, header->header.size); - time (&t); TIME_TO_CHARS (t, header->header.mtime); MODE_TO_CHARS (S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, header->header.mode); UID_TO_CHARS (getuid (), header->header.uid); @@ -563,13 +561,13 @@ write_gnu_long_link (struct tar_stat_info *st, const char *p, char type) union block *header; char *tmpname; - header = start_private_header ("././@LongLink", size); - FILL(header->header.mtime, '0'); - FILL(header->header.mode, '0'); - FILL(header->header.uid, '0'); - FILL(header->header.gid, '0'); - FILL(header->header.devmajor, 0); - FILL(header->header.devminor, 0); + header = start_private_header ("././@LongLink", size, time (NULL)); + FILL (header->header.mtime, '0'); + FILL (header->header.mode, '0'); + FILL (header->header.uid, '0'); + FILL (header->header.gid, '0'); + FILL (header->header.devmajor, 0); + FILL (header->header.devminor, 0); uid_to_uname (0, &tmpname); UNAME_TO_CHARS (tmpname, header->header.uname); free (tmpname); @@ -712,7 +710,8 @@ write_extended (bool global, struct tar_stat_info *st, union block *old_header) union block *header, hp; char *p; int type; - + time_t t; + if (st->xhdr.buffer || st->xhdr.stk == NULL) return old_header; @@ -722,13 +721,15 @@ write_extended (bool global, struct tar_stat_info *st, union block *old_header) { type = XGLTYPE; p = xheader_ghdr_name (); + time (&t); } else { type = XHDTYPE; p = xheader_xhdr_name (st); + t = st->stat.st_mtime; } - xheader_write (type, p, &st->xhdr); + xheader_write (type, p, t, &st->xhdr); free (p); header = find_next_block (); memcpy (header, &hp.buffer, sizeof (hp.buffer)); diff --git a/src/xheader.c b/src/xheader.c index c779c0a..e8fd6a2 100644 --- a/src/xheader.c +++ b/src/xheader.c @@ -364,14 +364,14 @@ xheader_ghdr_name (void) } void -xheader_write (char type, char *name, struct xheader *xhdr) +xheader_write (char type, char *name, time_t t, struct xheader *xhdr) { union block *header; size_t size; char *p; size = xhdr->size; - header = start_private_header (name, size); + header = start_private_header (name, size, t); header->header.typeflag = type; simple_finish_header (header); @@ -413,7 +413,7 @@ xheader_write_global (struct xheader *xhdr) for (kp = keyword_global_override_list; kp; kp = kp->next) code_string (kp->value, kp->pattern, xhdr); xheader_finish (xhdr); - xheader_write (XGLTYPE, name = xheader_ghdr_name (), xhdr); + xheader_write (XGLTYPE, name = xheader_ghdr_name (), time (NULL), xhdr); free (name); } -- 2.45.2