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>
#include <quotearg.h>
#include <errno.h>
+#include <xgetcwd.h>
#if HAVE_UTIME_H
# include <utime.h>
we_are_root = geteuid () == 0;
same_permissions_option += we_are_root;
same_owner_option += we_are_root;
- xalloc_fail_func = extract_finish;
+ /* Save 'root device' to avoid purging mount points.
+ FIXME: Should the same be done after handling -C option ? */
+ if (one_file_system_option)
+ {
+ struct stat st;
+ char *dir = xgetcwd ();
+
+ if (deref_stat (true, dir, &st))
+ stat_diag (dir);
+ else
+ root_device = st.st_dev;
+ }
+
/* Option -p clears the kernel umask, so it does not affect proper
restoration of file permissions. New intermediate directories will
comply with umask at start of program. */
static int
make_directories (char *file_name)
{
- char *cursor0 = file_name + FILESYSTEM_PREFIX_LEN (file_name);
+ char *cursor0 = file_name + FILE_SYSTEM_PREFIX_LEN (file_name);
char *cursor; /* points into the file name */
int did_something = 0; /* did we do anything yet? */
int mode;
switch (old_files_option)
{
case UNLINK_FIRST_OLD_FILES:
- if (!remove_any_file (file_name, recursive_unlink_option)
+ if (!remove_any_file (file_name,
+ recursive_unlink_option ? RECURSIVE_REMOVE_OPTION
+ : ORDINARY_REMOVE_OPTION)
&& errno && errno != ENOENT)
{
unlink_error (file_name);
case NO_OVERWRITE_DIR_OLD_FILES:
case OVERWRITE_OLD_FILES:
{
- int r = remove_any_file (file_name, 0);
+ int r = remove_any_file (file_name, ORDINARY_REMOVE_OPTION);
errno = EEXIST;
return r;
}
break;
if (absolute_names_option
- || ! (ISSLASH (current_stat_info.link_name
- [FILESYSTEM_PREFIX_LEN (current_stat_info.link_name)])
+ || ! (IS_ABSOLUTE_FILE_NAME (current_stat_info.link_name)
|| contains_dot_dot (current_stat_info.link_name)))
{
while (status = symlink (current_stat_info.link_name, file_name),
/* MSDOS does not implement links. However, djgpp's link() actually
copies the file. */
status = link (link_name, file_name);
+ e = errno;
if (status == 0)
{
struct delayed_symlink *ds = delayed_symlink_head;
- if (ds && stat (link_name, &st1) == 0)
+ if (ds && lstat (link_name, &st1) == 0)
for (; ds; ds = ds->next)
if (ds->dev == st1.st_dev
&& ds->ino == st1.st_ino
}
break;
}
+
+ if ((e == EEXIST && strcmp (link_name, file_name) == 0)
+ || (lstat (link_name, &st1) == 0
+ && lstat (file_name, &st2) == 0
+ && st1.st_dev == st2.st_dev
+ && st1.st_ino == st2.st_ino))
+ break;
+
+ errno = e;
if (maybe_recoverable (file_name, &interdir_made))
goto again_link;
if (incremental_option && errno == EEXIST)
break;
- e = errno;
- if (stat (link_name, &st1) == 0
- && stat (file_name, &st2) == 0
- && st1.st_dev == st2.st_dev
- && st1.st_ino == st2.st_ino)
- break;
link_error (link_name, file_name);
if (backup_option)
/* Read the entry and delete files that aren't listed in the
archive. */
- gnu_restore (file_name);
+ purge_directory (file_name);
}
else if (typeflag == GNUTYPE_DUMPDIR)
skip_member ();
error (TAREXIT_FAILURE, 0, _("Error is not recoverable: exiting now"));
abort ();
}
+
+void
+xalloc_die (void)
+{
+ error (0, 0, "%s", _("memory exhausted"));
+ fatal_exit ();
+}