X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fcreate.c;h=59231ac51d466c1f6456ee1a4316996389956f11;hb=2de1477b3d5cba5876883e320c9eb0523fb77b3c;hp=7cecd4f9e290839c43f0ccf530009088af4c3a34;hpb=3cdbeffe307bad27a2f947f3527db4f27041e8b4;p=chaz%2Ftar diff --git a/src/create.c b/src/create.c index 7cecd4f..59231ac 100644 --- a/src/create.c +++ b/src/create.c @@ -186,6 +186,8 @@ to_chars (int negative, 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. */ uintmax_t s = (negsub &= archive_format == GNU_FORMAT) ? - sub : sub; char subbuf[UINTMAX_STRSIZE_BOUND + 1]; char *sub_string = STRINGIFY_BIGINT (s, subbuf + 1); @@ -369,7 +371,7 @@ tar_copy_str (char *dst, const char *src, size_t len) } /* Write a "private" header */ -static union block * +union block * start_private_header (const char *name, size_t size) { time_t t; @@ -413,6 +415,7 @@ write_gnu_long_link (struct tar_stat_info *st, const char *p, char type) union block *header; header = start_private_header ("././@LongLink", size); + strcpy (header->header.magic, OLDGNU_MAGIC); header->header.typeflag = type; finish_header (st, header, -1); @@ -486,7 +489,7 @@ write_long_link (struct tar_stat_info *st) switch (archive_format) { case POSIX_FORMAT: - xheader_store ("linkpath", st); + xheader_store ("linkpath", st, NULL); break; case V7_FORMAT: /* old V7 tar format */ @@ -513,7 +516,7 @@ write_long_name (struct tar_stat_info *st) switch (archive_format) { case POSIX_FORMAT: - xheader_store ("path", st); + xheader_store ("path", st, NULL); break; case V7_FORMAT: @@ -531,9 +534,9 @@ write_long_name (struct tar_stat_info *st) } return write_short_name (st); } - + static union block * -write_extended (struct tar_stat_info *st, union block *old_header, char type) +write_extended (struct tar_stat_info *st, union block *old_header) { union block *header, hp; size_t size; @@ -543,35 +546,10 @@ write_extended (struct tar_stat_info *st, union block *old_header, char type) return old_header; xheader_finish (&extended_header); - size = extended_header.size; - memcpy (hp.buffer, old_header, sizeof (hp)); - - header = start_private_header ("././@PaxHeader", size); - header->header.typeflag = type; - - finish_header (st, header, -1); - - p = extended_header.buffer; - - do - { - size_t len; - - header = find_next_block (); - len = BLOCKSIZE; - if (len > size) - len = size; - memcpy (header->buffer, p, len); - if (len < BLOCKSIZE) - memset (header->buffer + len, 0, BLOCKSIZE - len); - p += len; - size -= len; - set_next_block_after (header); - } - while (size > 0); - - xheader_destroy (&extended_header); + p = xheader_xhdr_name (st); + xheader_write (XHDTYPE, p, &extended_header); + free (p); header = find_next_block (); memcpy (header, &hp.buffer, sizeof (hp.buffer)); return header; @@ -640,17 +618,17 @@ start_header (struct tar_stat_info *st) MODE_TO_CHARS (st->stat.st_mode, header->header.mode); if (st->stat.st_uid > MAXOCTAL7 && archive_format == POSIX_FORMAT) - xheader_store ("uid", st); + xheader_store ("uid", st, NULL); else UID_TO_CHARS (st->stat.st_uid, header->header.uid); if (st->stat.st_gid > MAXOCTAL7 && archive_format == POSIX_FORMAT) - xheader_store ("gid", st); + xheader_store ("gid", st, NULL); else GID_TO_CHARS (st->stat.st_gid, header->header.gid); if (st->stat.st_size > MAXOCTAL11 && archive_format == POSIX_FORMAT) - xheader_store ("size", st); + xheader_store ("size", st, NULL); else OFF_TO_CHARS (st->stat.st_size, header->header.size); @@ -664,12 +642,12 @@ start_header (struct tar_stat_info *st) st->devminor = minor (st->stat.st_rdev); if (st->devmajor > MAXOCTAL7 && archive_format == POSIX_FORMAT) - xheader_store ("devmajor", st); + xheader_store ("devmajor", st, NULL); else MAJOR_TO_CHARS (st->devmajor, header->header.devmajor); if (st->devminor > MAXOCTAL7 && archive_format == POSIX_FORMAT) - xheader_store ("devminor", st); + xheader_store ("devminor", st, NULL); else MAJOR_TO_CHARS (st->devminor, header->header.devminor); } @@ -681,8 +659,8 @@ start_header (struct tar_stat_info *st) if (archive_format == POSIX_FORMAT) { - xheader_store ("atime", st); - xheader_store ("ctime", st); + xheader_store ("atime", st, NULL); + xheader_store ("ctime", st, NULL); } else if (incremental_option) if (archive_format == OLDGNU_FORMAT) @@ -725,13 +703,13 @@ start_header (struct tar_stat_info *st) if (archive_format == POSIX_FORMAT && strlen (st->uname) > UNAME_FIELD_SIZE) - xheader_store ("uname", st); + xheader_store ("uname", st, NULL); else UNAME_TO_CHARS (st->uname, header->header.uname); if (archive_format == POSIX_FORMAT && strlen (st->gname) > GNAME_FIELD_SIZE) - xheader_store ("gname", st); + xheader_store ("gname", st, NULL); else GNAME_TO_CHARS (st->gname, header->header.gname); } @@ -739,35 +717,13 @@ start_header (struct tar_stat_info *st) return header; } -/* Finish off a filled-in header block and write it out. We also - print the file name and/or full info if verbose is on. If BLOCK_ORDINAL - is not negative, is the block ordinal of the first record for this - file, which may be a preceding long name or long link record. */ void -finish_header (struct tar_stat_info *st, - union block *header, off_t block_ordinal) +simple_finish_header (union block *header) { size_t i; int sum; char *p; - /* Note: It is important to do this before the call to write_extended(), - so that the actual ustar header is printed */ - if (verbose_option - && header->header.typeflag != GNUTYPE_LONGLINK - && header->header.typeflag != GNUTYPE_LONGNAME - && header->header.typeflag != XHDTYPE - && header->header.typeflag != XGLTYPE) - { - /* These globals are parameters to print_header, sigh. */ - - current_header = header; - current_format = archive_format; - print_header (st, block_ordinal); - } - - header = write_extended (st, header, XHDTYPE); - memcpy (header->header.chksum, CHKBLANKS, sizeof header->header.chksum); sum = 0; @@ -790,6 +746,37 @@ finish_header (struct tar_stat_info *st, set_next_block_after (header); } + +/* Finish off a filled-in header block and write it out. We also + print the file name and/or full info if verbose is on. If BLOCK_ORDINAL + is not negative, is the block ordinal of the first record for this + file, which may be a preceding long name or long link record. */ +void +finish_header (struct tar_stat_info *st, + union block *header, off_t block_ordinal) +{ + size_t i; + int sum; + char *p; + + /* Note: It is important to do this before the call to write_extended(), + so that the actual ustar header is printed */ + if (verbose_option + && header->header.typeflag != GNUTYPE_LONGLINK + && header->header.typeflag != GNUTYPE_LONGNAME + && header->header.typeflag != XHDTYPE + && header->header.typeflag != XGLTYPE) + { + /* These globals are parameters to print_header, sigh. */ + + current_header = header; + current_format = archive_format; + print_header (st, block_ordinal); + } + + header = write_extended (st, header); + simple_finish_header (header); +} void @@ -980,11 +967,13 @@ dump_dir0 (char *directory, return; } } - else if (!recursion_option) + + if (!recursion_option) return; - else if (one_file_system_option - && !top_level - && parent_device != stat->stat.st_dev) + + if (one_file_system_option + && !top_level + && parent_device != stat->stat.st_dev) { if (verbose_option) WARN ((0, 0, @@ -1063,7 +1052,8 @@ create_archive (void) char *p; open_archive (ACCESS_WRITE); - + xheader_write_global (); + if (incremental_option) { size_t buffer_size = 1000; @@ -1178,7 +1168,7 @@ dump_hard_link (struct tar_stat_info *stat) if ((dup = hash_lookup (link_table, &lp))) { /* We found a link. */ - char const *link_name = safer_name_suffix (dup->name, 1); + char const *link_name = safer_name_suffix (dup->name, true); dup->nlink--; @@ -1274,7 +1264,7 @@ dump_file0 (struct tar_stat_info *stat, char *p, return; assign_string (&stat->orig_file_name, p); - assign_string (&stat->file_name, safer_name_suffix (p, 0)); + assign_string (&stat->file_name, safer_name_suffix (p, false)); if (deref_stat (dereference_option, p, &stat->stat) != 0) { @@ -1282,7 +1272,7 @@ dump_file0 (struct tar_stat_info *stat, char *p, return; } stat->archive_file_size = stat->stat.st_size; - + sys_stat_nanoseconds(stat); original_ctime = stat->stat.st_ctime; restore_times.actime = stat->stat.st_atime; restore_times.modtime = stat->stat.st_mtime; @@ -1303,12 +1293,11 @@ dump_file0 (struct tar_stat_info *stat, char *p, /* See if we want only new files, and check if this one is too old to put in the archive. */ - if ((0 < top_level || !incremental_option) - && !S_ISDIR (stat->stat.st_mode) + if (!S_ISDIR (stat->stat.st_mode) && stat->stat.st_mtime < newer_mtime_option && (!after_date_option || stat->stat.st_ctime < newer_ctime_option)) { - if (0 < top_level) + if (0 < top_level) /* equivalent to !incremental_option */ WARN ((0, 0, _("%s: file is unchanged; not dumped"), quotearg_colon (p))); /* FIXME: recheck this return. */