/* Extract files from a tar archive.
- Copyright 1988, 1992-1994, 1996-2001, 2003-2007, 2010, 2012-2013
- Free Software Foundation, Inc.
+ Copyright 1988, 1992-1994, 1996-2001, 2003-2007, 2010, 2012-2014 Free
+ Software Foundation, Inc.
This file is part of GNU tar.
umask (newdir_umask); /* restore the kernel umask */
current_umask = newdir_umask;
}
-
- /* If the user wants to guarantee that everything is under one directory,
- determine its name now and let it be created later. */
- if (one_top_level_option)
- {
- int i;
- char *base = base_name (archive_name_array[0]);
-
- for (i = strlen (base) - 1; i > 2; i--)
- if (!strncmp (base + i - 3, ".tar", 4) ||
- !strncmp (base + i - 3, ".taz", 4) ||
- !strncmp (base + i - 3, ".tbz", 4) ||
- !strncmp (base + i - 3, ".tb2", 4) ||
- !strncmp (base + i - 3, ".tgz", 4) ||
- !strncmp (base + i - 3, ".tlz", 4) ||
- !strncmp (base + i - 3, ".txz", 4)) break;
-
- if (i <= 3)
- {
- one_top_level_option = false;
- free (base);
- return;
- }
-
- one_top_level = xmalloc (i - 2);
- strncpy (one_top_level, base, i - 3);
- one_top_level[i - 3] = '\0';
- free (base);
- }
}
/* Use fchmod if possible, fchmodat otherwise. */
quotearg_colon (dir)));
}
+static void
+free_delayed_set_stat (struct delayed_set_stat *data)
+{
+ xheader_xattr_free (data->xattr_map, data->xattr_map_size);
+ free (data->cntx_name);
+ free (data->acls_a_ptr);
+ free (data->acls_d_ptr);
+ free (data);
+}
+
+void
+remove_delayed_set_stat (const char *fname)
+{
+ struct delayed_set_stat *data, *next, *prev = NULL;
+ for (data = delayed_set_stat_head; data; data = next)
+ {
+ next = data->next;
+ if (chdir_current == data->change_dir
+ && strcmp (data->file_name, fname) == 0)
+ {
+ free_delayed_set_stat (data);
+ if (prev)
+ prev->next = next;
+ else
+ delayed_set_stat_head = next;
+ return;
+ }
+ else
+ prev = data;
+ }
+}
+
/* After a file/link/directory creation has failed, see if
it's because some required directory was not present, and if so,
create all required directories. Return zero if all the required
}
delayed_set_stat_head = data->next;
- xheader_xattr_free (data->xattr_map, data->xattr_map_size);
- free (data->cntx_name);
- free (data->acls_a_ptr);
- free (data->acls_d_ptr);
- free (data);
+ free_delayed_set_stat (data);
}
}
return 1;
}
-void
-maybe_prepend_name (char **file_name)
-{
- int i;
-
- for (i = 0; i < strlen (*file_name); i++)
- if (!ISSLASH ((*file_name)[i]) && (*file_name)[i] != '.') break;
-
- if (i == strlen (*file_name))
- return;
-
- if (!strncmp (*file_name + i, one_top_level, strlen (one_top_level)))
- {
- int pos = i + strlen (one_top_level);
- if (ISSLASH ((*file_name)[pos]) || (*file_name)[pos] == '\0') return;
- }
-
- char *new_name = xmalloc (strlen (one_top_level) + strlen (*file_name) + 2);
-
- strcpy (new_name, one_top_level);
- strcat (new_name, "/");
- strcat (new_name, *file_name);
-
- free (*file_name);
- *file_name = new_name;
-}
-
/* Extract a file from the archive. */
void
extract_archive (void)
typeflag = sparse_member_p (¤t_stat_info) ?
GNUTYPE_SPARSE : current_header->header.typeflag;
- if (one_top_level_option)
- maybe_prepend_name (¤t_stat_info.file_name);
-
if (prepare_to_extract (current_stat_info.file_name, typeflag, &fun))
{
if (fun && (*fun) (current_stat_info.file_name, typeflag)