X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=src%2Fcreate.c;h=6eb6ad259e4b2d2bce8797e726f509994ab6278b;hb=01d61882973471f72122667e186331fdb6eee342;hp=eb528be25626e9db921a1012ed5608821888a51a;hpb=8ad985ea6c89f2bb21d4655973ebdb542f7bb39a;p=chaz%2Ftar diff --git a/src/create.c b/src/create.c index eb528be..6eb6ad2 100644 --- a/src/create.c +++ b/src/create.c @@ -152,8 +152,13 @@ to_chars_subst (int negative, int gnu_format, uintmax_t value, size_t valsize, { int negsub; uintmax_t sub = substitute (&negsub) & maxval; - /* FIXME: This is the only place where GNU_FORMAT differs from - OLDGNU_FORMAT. Apart from this they are completely identical. */ + /* NOTE: This is one of the few places where GNU_FORMAT differs from + OLDGNU_FORMAT. The actual differences are: + + 1. In OLDGNU_FORMAT all strings in a tar header end in \0 + 2. Incremental archives use oldgnu_header. + + Apart from this they are completely identical. */ uintmax_t s = (negsub &= archive_format == GNU_FORMAT) ? - sub : sub; char subbuf[UINTMAX_STRSIZE_BOUND + 1]; char *sub_string = STRINGIFY_BIGINT (s, subbuf + 1); @@ -291,7 +296,8 @@ mode_to_chars (mode_t v, char *p, size_t s) && S_IROTH == TOREAD && S_IWOTH == TOWRITE && S_IXOTH == TOEXEC && archive_format != POSIX_FORMAT && archive_format != USTAR_FORMAT - && archive_format != GNU_FORMAT) + && archive_format != GNU_FORMAT + && archive_format != OLDGNU_FORMAT) { negative = v < 0; u = v; @@ -736,7 +742,7 @@ start_header (struct tar_stat_info *st) { if (MAX_OCTAL_VAL (header->header.mtime) < mtime.tv_sec || mtime.tv_nsec != 0) - xheader_store ("mtime", st, NULL); + xheader_store ("mtime", st, &mtime); if (MAX_OCTAL_VAL (header->header.mtime) < mtime.tv_sec) mtime.tv_sec = 0; } @@ -968,8 +974,8 @@ dump_regular_file (int fd, struct tar_stat_info *st) size_left), quotearg_colon (st->orig_file_name), STRINGIFY_BIGINT (size_left, buf))); - if (! ignore_failed_read_option) - exit_status = TAREXIT_FAILURE; + if (! ignore_failed_read_option) + exit_status = TAREXIT_DIFFERS; pad_archive (size_left - (bufsize-count)); return dump_status_short; } @@ -1393,6 +1399,7 @@ dump_file0 (struct tar_stat_info *st, const char *p, { union block *header; char type; + off_t original_size; struct timespec original_ctime; struct timespec restore_times[2]; off_t block_ordinal = -1; @@ -1412,7 +1419,7 @@ dump_file0 (struct tar_stat_info *st, const char *p, stat_diag (p); return; } - st->archive_file_size = st->stat.st_size; + st->archive_file_size = original_size = st->stat.st_size; st->atime = restore_times[0] = get_stat_atime (&st->stat); st->mtime = restore_times[1] = get_stat_mtime (&st->stat); st->ctime = original_ctime = get_stat_ctime (&st->stat); @@ -1549,9 +1556,14 @@ dump_file0 (struct tar_stat_info *st, const char *p, if (ok) { - if (timespec_cmp (get_stat_ctime (&final_stat), original_ctime) != 0) - WARN ((0, 0, _("%s: file changed as we read it"), - quotearg_colon (p))); + if (timespec_cmp (get_stat_ctime (&final_stat), original_ctime) != 0 + || original_size < final_stat.st_size) + { + WARN ((0, 0, _("%s: file changed as we read it"), + quotearg_colon (p))); + if (exit_status == TAREXIT_SUCCESS) + exit_status = TAREXIT_DIFFERS; + } else if (atime_preserve_option == replace_atime_preserve && set_file_atime (fd, p, restore_times) != 0) utime_error (p);