/* Diff files from a tar archive.
Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
- 2003 Free Software Foundation, Inc.
+ 2003, 2004 Free Software Foundation, Inc.
Written by John Gilmore, on 1987-04-30.
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-#include "system.h"
+#include <system.h>
#if HAVE_UTIME_H
# include <utime.h>
#include <quotearg.h>
#include "common.h"
-#include "rmt.h"
+#include <rmt.h>
#include <stdarg.h>
/* Nonzero if we are verifying at the moment. */
void
diff_init (void)
{
- diff_buffer = valloc (record_size);
- if (!diff_buffer)
- xalloc_die ();
+ void *ptr;
+ diff_buffer = page_aligned_alloc (&ptr, record_size);
}
/* Sigh about something that differs by writing a MESSAGE to stdlis,
given MESSAGE is nonzero. Also set the exit status if not already. */
void
-report_difference (const char *fmt, ...)
+report_difference (struct tar_stat_info *st __attribute__ ((unused)),
+ const char *fmt, ...)
{
if (fmt)
{
va_end (ap);
fprintf (stdlis, "\n");
}
-
+
if (exit_status == TAREXIT_SUCCESS)
exit_status = TAREXIT_DIFFERS;
}
/* Take a buffer returned by read_and_process and do nothing with it. */
static int
-process_noop (size_t size, char *data)
+process_noop (size_t size __attribute__ ((unused)),
+ char *data __attribute__ ((unused)))
{
- /* Yes, I know. SIZE and DATA are unused in this function. Some
- compilers may even report it. That's OK, just relax! */
return 1;
}
static int
process_rawdata (size_t bytes, char *buffer)
{
- ssize_t status = safe_read (diff_handle, diff_buffer, bytes);
+ size_t status = safe_read (diff_handle, diff_buffer, bytes);
if (status != bytes)
{
- if (status < 0)
+ if (status == SAFE_READ_ERROR)
{
read_error (current_stat_info.file_name);
- report_difference (NULL);
+ report_difference (¤t_stat_info, NULL);
}
else
{
- report_difference (ngettext ("Could only read %lu of %lu byte",
+ report_difference (¤t_stat_info,
+ ngettext ("Could only read %lu of %lu byte",
"Could only read %lu of %lu bytes",
bytes),
(unsigned long) status, (unsigned long) bytes);
if (memcmp (buffer, diff_buffer, bytes))
{
- report_difference (_("Contents differ"));
+ report_difference (¤t_stat_info,
+ _("Contents differ"));
return 0;
}
{
if (memcmp (buffer, dumpdir_cursor, bytes))
{
- report_difference (_("Contents differ"));
+ report_difference (¤t_stat_info, _("Contents differ"));
return 0;
}
}
}
-static void
-diff_sparse_files (void)
-{
- /*FIXME!!*/abort();
-}
-
/* Call either stat or lstat over STAT_DATA, depending on
--dereference (-h), for a file which should exist. Diagnose any
problem. Return nonzero for success, zero otherwise. */
stat_warn (file_name);
else
stat_error (file_name);
- report_difference (NULL);
+ report_difference (¤t_stat_info, NULL);
return 0;
}
if (!S_ISREG (stat_data.st_mode))
{
- report_difference (_("File type differs"));
+ report_difference (¤t_stat_info, _("File type differs"));
skip_member ();
goto quit;
}
- if ((current_stat_info.stat.st_mode & MODE_ALL) != (stat_data.st_mode & MODE_ALL))
- report_difference (_("Mode differs"));
+ if ((current_stat_info.stat.st_mode & MODE_ALL) !=
+ (stat_data.st_mode & MODE_ALL))
+ report_difference (¤t_stat_info, _("Mode differs"));
- sys_compare_uid_gid (&stat_data, ¤t_stat_info.stat);
+ if (!sys_compare_uid (&stat_data, ¤t_stat_info.stat))
+ report_difference (¤t_stat_info, _("Uid differs"));
+ if (!sys_compare_gid (&stat_data, ¤t_stat_info.stat))
+ report_difference (¤t_stat_info, _("Gid differs"));
if (stat_data.st_mtime != current_stat_info.stat.st_mtime)
- report_difference (_("Mod time differs"));
+ report_difference (¤t_stat_info, _("Mod time differs"));
if (current_header->header.typeflag != GNUTYPE_SPARSE &&
stat_data.st_size != current_stat_info.stat.st_size)
{
- report_difference (_("Size differs"));
+ report_difference (¤t_stat_info, _("Size differs"));
skip_member ();
goto quit;
}
{
open_error (current_stat_info.file_name);
skip_member ();
- report_difference (NULL);
+ report_difference (¤t_stat_info, NULL);
goto quit;
}
/* Need to treat sparse files completely differently here. */
- if (current_header->header.typeflag == GNUTYPE_SPARSE)
- diff_sparse_files ();
+ if (current_stat_info.is_sparse)
+ sparse_diff_file (diff_handle, ¤t_stat_info);
else
{
if (multi_volume_option)
case LNKTYPE:
{
- struct stat link_data, stat_data;
+ struct stat file_data;
+ struct stat link_data;
- if (!get_stat_data (current_stat_info.file_name, &stat_data))
+ if (!get_stat_data (current_stat_info.file_name, &file_data))
break;
if (!get_stat_data (current_stat_info.link_name, &link_data))
break;
- sys_compare_links (&stat_data, &link_data);
+ if (!sys_compare_links (&file_data, &link_data))
+ report_difference (¤t_stat_info,
+ _("Not linked to %s"),
+ quote (current_stat_info.link_name));
}
break;
-
+
#ifdef HAVE_READLINK
case SYMTYPE:
{
readlink_warn (current_stat_info.file_name);
else
readlink_error (current_stat_info.file_name);
- report_difference (NULL);
+ report_difference (¤t_stat_info, NULL);
}
else if (status != len
|| strncmp (current_stat_info.link_name, linkbuf, len) != 0)
- report_difference (_("Symlink differs"));
+ report_difference (¤t_stat_info, _("Symlink differs"));
break;
}
: /* current_header->header.typeflag == FIFOTYPE */
!S_ISFIFO (stat_data.st_mode))
{
- report_difference (_("File type differs"));
+ report_difference (¤t_stat_info, _("File type differs"));
break;
}
|| current_header->header.typeflag == BLKTYPE)
&& current_stat_info.stat.st_rdev != stat_data.st_rdev)
{
- report_difference (_("Device number differs"));
+ report_difference (¤t_stat_info, _("Device number differs"));
break;
}
if ((current_stat_info.stat.st_mode & MODE_ALL) != (stat_data.st_mode & MODE_ALL))
{
- report_difference (_("Mode differs"));
+ report_difference (¤t_stat_info, _("Mode differs"));
break;
}
if (!S_ISDIR (stat_data.st_mode))
{
- report_difference (_("File type differs"));
+ report_difference (¤t_stat_info, _("File type differs"));
break;
}
if ((current_stat_info.stat.st_mode & MODE_ALL) != (stat_data.st_mode & MODE_ALL))
{
- report_difference (_("Mode differs"));
+ report_difference (¤t_stat_info, _("Mode differs"));
break;
}
if (!S_ISREG (stat_data.st_mode))
{
- report_difference (_("File type differs"));
+ report_difference (¤t_stat_info, _("File type differs"));
skip_member ();
break;
}
offset = OFF_FROM_HEADER (current_header->oldgnu_header.offset);
if (stat_data.st_size != current_stat_info.stat.st_size + offset)
{
- report_difference (_("Size differs"));
+ report_difference (¤t_stat_info, _("Size differs"));
skip_member ();
break;
}
if (diff_handle < 0)
{
open_error (current_stat_info.file_name);
- report_difference (NULL);
+ report_difference (¤t_stat_info, NULL);
skip_member ();
break;
}
if (lseek (diff_handle, offset, SEEK_SET) < 0)
{
seek_error_details (current_stat_info.file_name, offset);
- report_difference (NULL);
+ report_difference (¤t_stat_info, NULL);
break;
}
void
verify_volume (void)
{
+ if (removed_prefixes_p ())
+ {
+ WARN((0, 0,
+ _("Archive contains file names with leading prefixes removed.")));
+ WARN((0, 0,
+ _("Verification may fail to locate original files.")));
+ }
+
if (!diff_buffer)
diff_init ();
do
{
counter++;
+ set_next_block_after (current_header);
status = read_header (false);
}
while (status == HEADER_FAILURE);
break;
diff_archive ();
+ tar_stat_destroy (¤t_stat_info);
+ xheader_destroy (&extended_header);
}
access_mode = ACCESS_WRITE;