/* Create a tar archive.
Copyright (C) 1985, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
- 2003, 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
+ 2003, 2004, 2005, 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
Written by John Gilmore, on 1985-08-25.
{
size_t i;
- if (length > PREFIX_FIELD_SIZE)
+ if (length > PREFIX_FIELD_SIZE + 1)
length = PREFIX_FIELD_SIZE + 1;
+ else if (ISSLASH (name[length - 1]))
+ length--;
for (i = length - 1; i > 0; i--)
if (ISSLASH (name[i]))
break;
write_ustar_long_name (const char *name)
{
size_t length = strlen (name);
- size_t i;
+ size_t i, nlen;
union block *header;
-
+
if (length > PREFIX_FIELD_SIZE + NAME_FIELD_SIZE + 1)
{
ERROR ((0, 0, _("%s: file name is too long (max %d); not dumped"),
}
i = split_long_name (name, length);
- if (i == 0 || length - i - 1 > NAME_FIELD_SIZE)
+ if (i == 0 || (nlen = length - i - 1) > NAME_FIELD_SIZE || nlen == 0)
{
ERROR ((0, 0,
_("%s: file name is too long (cannot be split); not dumped"),
&& header->header.typeflag != XHDTYPE
&& header->header.typeflag != XGLTYPE)
{
- /* These globals are parameters to print_header, sigh. */
-
- current_header = header;
+ /* FIXME: This global is used in print_header, sigh. */
current_format = archive_format;
- print_header (st, block_ordinal);
+ print_header (st, header, block_ordinal);
}
header = write_extended (false, st, header);
{
dev_t our_device = st->stat.st_dev;
const char *tag_file_name;
-
- if (!is_avoided_name (st->orig_file_name))
- {
- union block *blk = NULL;
- off_t block_ordinal = current_block_ordinal ();
- st->stat.st_size = 0; /* force 0 size on dir */
+ union block *blk = NULL;
+ off_t block_ordinal = current_block_ordinal ();
- blk = start_header (st);
- if (!blk)
- return;
+ st->stat.st_size = 0; /* force 0 size on dir */
- if (incremental_option && archive_format != POSIX_FORMAT)
- blk->header.typeflag = GNUTYPE_DUMPDIR;
- else /* if (standard_option) */
- blk->header.typeflag = DIRTYPE;
+ blk = start_header (st);
+ if (!blk)
+ return;
- /* If we're gnudumping, we aren't done yet so don't close it. */
+ if (incremental_option && archive_format != POSIX_FORMAT)
+ blk->header.typeflag = GNUTYPE_DUMPDIR;
+ else /* if (standard_option) */
+ blk->header.typeflag = DIRTYPE;
- if (!incremental_option)
- finish_header (st, blk, block_ordinal);
- else if (gnu_list_name->directory)
+ /* If we're gnudumping, we aren't done yet so don't close it. */
+
+ if (!incremental_option)
+ finish_header (st, blk, block_ordinal);
+ else if (gnu_list_name->directory)
+ {
+ if (archive_format == POSIX_FORMAT)
{
- if (archive_format == POSIX_FORMAT)
- {
- xheader_store ("GNU.dumpdir", st,
- safe_directory_contents (gnu_list_name->directory));
- finish_header (st, blk, block_ordinal);
- }
- else
+ xheader_store ("GNU.dumpdir", st,
+ safe_directory_contents (gnu_list_name->directory));
+ finish_header (st, blk, block_ordinal);
+ }
+ else
+ {
+ off_t size_left;
+ off_t totsize;
+ size_t bufsize;
+ ssize_t count;
+ const char *buffer, *p_buffer;
+
+ block_ordinal = current_block_ordinal ();
+ buffer = safe_directory_contents (gnu_list_name->directory);
+ totsize = dumpdir_size (buffer);
+ OFF_TO_CHARS (totsize, blk->header.size);
+ finish_header (st, blk, block_ordinal);
+ p_buffer = buffer;
+ size_left = totsize;
+
+ mv_begin (st);
+ mv_total_size (totsize);
+ while (size_left > 0)
{
- off_t size_left;
- off_t totsize;
- size_t bufsize;
- ssize_t count;
- const char *buffer, *p_buffer;
-
- block_ordinal = current_block_ordinal ();
- buffer = safe_directory_contents (gnu_list_name->directory);
- totsize = dumpdir_size (buffer);
- OFF_TO_CHARS (totsize, blk->header.size);
- finish_header (st, blk, block_ordinal);
- p_buffer = buffer;
- size_left = totsize;
-
- mv_begin (st);
- mv_total_size (totsize);
- while (size_left > 0)
+ mv_size_left (size_left);
+ blk = find_next_block ();
+ bufsize = available_space_after (blk);
+ if (size_left < bufsize)
{
- mv_size_left (size_left);
- blk = find_next_block ();
- bufsize = available_space_after (blk);
- if (size_left < bufsize)
- {
- bufsize = size_left;
- count = bufsize % BLOCKSIZE;
- if (count)
- memset (blk->buffer + size_left, 0, BLOCKSIZE - count);
- }
- memcpy (blk->buffer, p_buffer, bufsize);
- size_left -= bufsize;
- p_buffer += bufsize;
- set_next_block_after (blk + (bufsize - 1) / BLOCKSIZE);
+ bufsize = size_left;
+ count = bufsize % BLOCKSIZE;
+ if (count)
+ memset (blk->buffer + size_left, 0, BLOCKSIZE - count);
}
- mv_end ();
+ memcpy (blk->buffer, p_buffer, bufsize);
+ size_left -= bufsize;
+ p_buffer += bufsize;
+ set_next_block_after (blk + (bufsize - 1) / BLOCKSIZE);
}
- return;
+ mv_end ();
}
+ return;
}
if (!recursion_option)
return;
}
- if (is_avoided_name (p))
- return;
-
is_dir = S_ISDIR (st->stat.st_mode) != 0;
if (!is_dir && dump_hard_link (st))