/* Create a tar archive.
Copyright (C) 1985, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
- 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ 2003, 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
Written by John Gilmore, on 1985-08-25.
}
enum exclusion_tag_type
-check_exclusion_tags (char *dirname, const char **tag_file_name)
+check_exclusion_tags (const char *dirname, const char **tag_file_name)
{
static char *tagname;
static size_t tagsize;
struct exclusion_tag *tag;
size_t dlen = strlen (dirname);
- int addslash = dirname[dlen-1] != '/';
+ int addslash = !ISSLASH (dirname[dlen-1]);
char *nptr = NULL;
for (tag = exclusion_tags; tag; tag = tag->next)
quotearg_colon (st->orig_file_name),
STRINGIFY_BIGINT (size_left, buf)));
if (! ignore_failed_read_option)
- exit_status = TAREXIT_DIFFERS;
+ set_exit_status (TAREXIT_DIFFERS);
pad_archive (size_left - (bufsize - count));
return dump_status_short;
}
\f
static void
dump_dir0 (char *directory,
- struct tar_stat_info *st, int top_level, dev_t parent_device)
+ struct tar_stat_info *st, bool top_level, dev_t parent_device)
{
dev_t our_device = st->stat.st_dev;
const char *tag_file_name;
if (!incremental_option)
finish_header (st, blk, block_ordinal);
- else if (gnu_list_name->dir_contents)
+ else if (gnu_list_name->directory)
{
if (archive_format == POSIX_FORMAT)
{
- xheader_store ("GNU.dumpdir", st, gnu_list_name->dir_contents);
+ xheader_store ("GNU.dumpdir", st,
+ safe_directory_contents (gnu_list_name->directory));
finish_header (st, blk, block_ordinal);
}
else
const char *buffer, *p_buffer;
block_ordinal = current_block_ordinal ();
- buffer = gnu_list_name->dir_contents;
- if (buffer)
- totsize = dumpdir_size (buffer);
- else
- totsize = 0;
+ 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;
}
strcpy (name_buf + name_len, entry);
if (!excluded_name (name_buf))
- dump_file (name_buf, 0, our_device);
+ dump_file (name_buf, false, our_device);
}
free (name_buf);
name_buf = xmalloc (name_size);
strcpy (name_buf, st->orig_file_name);
strcat (name_buf, tag_file_name);
- dump_file (name_buf, 0, our_device);
+ dump_file (name_buf, false, our_device);
free (name_buf);
break;
}
static bool
-dump_dir (int fd, struct tar_stat_info *st, int top_level, dev_t parent_device)
+dump_dir (int fd, struct tar_stat_info *st, bool top_level,
+ dev_t parent_device)
{
char *directory = fdsavedir (fd);
if (!directory)
void
create_archive (void)
{
- const char *p;
+ struct name const *p;
open_archive (ACCESS_WRITE);
buffer_write_global_xheader ();
collect_and_sort_names ();
while ((p = name_from_list ()) != NULL)
- if (!excluded_name (p))
- dump_file (p, -1, (dev_t) 0);
+ if (!excluded_name (p->name))
+ dump_file (p->name, p->cmdline, (dev_t) 0);
blank_name_list ();
while ((p = name_from_list ()) != NULL)
- if (!excluded_name (p))
+ if (!excluded_name (p->name))
{
- size_t plen = strlen (p);
+ size_t plen = strlen (p->name);
if (buffer_size <= plen)
{
while ((buffer_size *= 2) <= plen)
continue;
buffer = xrealloc (buffer, buffer_size);
}
- memcpy (buffer, p, plen);
+ memcpy (buffer, p->name, plen);
if (! ISSLASH (buffer[plen - 1]))
- buffer[plen++] = '/';
- q = gnu_list_name->dir_contents;
+ buffer[plen++] = DIRECTORY_SEPARATOR;
+ q = directory_contents (gnu_list_name->directory);
if (q)
while (*q)
{
buffer = xrealloc (buffer, buffer_size);
}
strcpy (buffer + plen, q + 1);
- dump_file (buffer, -1, (dev_t) 0);
+ dump_file (buffer, false, (dev_t) 0);
}
q += qlen + 1;
}
}
else
{
- while ((p = name_next (1)) != NULL)
- if (!excluded_name (p))
- dump_file (p, 1, (dev_t) 0);
+ const char *name;
+ while ((name = name_next (1)) != NULL)
+ if (!excluded_name (name))
+ dump_file (name, true, (dev_t) 0);
}
write_eot ();
(0, 0, _("%s: Unknown file type; file ignored"),
quotearg_colon (p)));
if (!ignore_failed_read_option)
- exit_status = TAREXIT_FAILURE;
+ set_exit_status (TAREXIT_FAILURE);
}
\f
}
}
-
/* Dump a single file, recursing on directories. P is the file name
to dump. TOP_LEVEL tells whether this is a top-level call; zero
means no, positive means yes, and negative means the top level
static void
dump_file0 (struct tar_stat_info *st, const char *p,
- int top_level, dev_t parent_device)
+ bool top_level, dev_t parent_device)
{
union block *header;
char type;
if (deref_stat (dereference_option, p, &st->stat) != 0)
{
- stat_diag (p);
+ file_removed_diag (p, top_level, stat_diag);
return;
}
st->archive_file_size = original_size = st->stat.st_size;
/* See if we want only new files, and check if this one is too old to
put in the archive.
-
+
This check is omitted if incremental_option is set *and* the
requested file is not explicitely listed in the command line. */
-
+
if (!(incremental_option && !is_individual_file (p))
&& !S_ISDIR (st->stat.st_mode)
&& OLDER_TAR_STAT_TIME (*st, m)
: 0)));
if (fd < 0)
{
- if (!top_level && errno == ENOENT)
- WARNOPT (WARN_FILE_REMOVED,
- (0, 0, _("%s: File removed before we read it"),
- quotearg_colon (p)));
- else
- open_diag (p);
+ file_removed_diag (p, top_level, open_diag);
return;
}
}
: fstat (fd, &final_stat))
!= 0)
{
- stat_diag (p);
+ file_removed_diag (p, top_level, stat_diag);
ok = false;
}
}
WARNOPT (WARN_FILE_CHANGED,
(0, 0, _("%s: file changed as we read it"),
quotearg_colon (p)));
- if (exit_status == TAREXIT_SUCCESS)
- exit_status = TAREXIT_DIFFERS;
+ set_exit_status (TAREXIT_DIFFERS);
}
else if (atime_preserve_option == replace_atime_preserve
&& set_file_atime (fd, p, restore_times) != 0)
size = readlink (p, buffer, linklen + 1);
if (size < 0)
{
- readlink_diag (p);
+ file_removed_diag (p, top_level, readlink_diag);
return;
}
buffer[size] = '\0';
}
void
-dump_file (const char *p, int top_level, dev_t parent_device)
+dump_file (const char *p, bool top_level, dev_t parent_device)
{
struct tar_stat_info st;
tar_stat_init (&st);