/* List a tar archive, with support routines for reading a tar archive.
Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000,
- 2001, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ 2001, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
Written by John Gilmore, on 1985-08-26.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any later
+ Free Software Foundation; either version 3, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but
{
prev_status = status;
tar_stat_destroy (¤t_stat_info);
- xheader_destroy (&extended_header);
status = read_header (false);
switch (status)
{
case GNUTYPE_VOLHDR:
case GNUTYPE_MULTIVOL:
- case GNUTYPE_NAMES:
break;
case DIRTYPE:
}
/* Read a block that's supposed to be a header block. Return its
- address in "current_header", and if it is good, the file's size in
- current_stat_info.stat.st_size.
+ address in "current_header", and if it is good, the file's size
+ and names (file name, link name) in *info.
Return 1 for success, 0 if the checksum is bad, EOF on eof, 2 for a
block full of zeros (EOF marker).
the header which this routine reads. */
enum read_header
-read_header (bool raw_extended_headers)
+read_header_primitive (bool raw_extended_headers, struct tar_stat_info *info)
{
union block *header;
union block *header_copy;
size_t size, written;
union block *next_long_name = 0;
union block *next_long_link = 0;
- size_t next_long_name_blocks;
- size_t next_long_link_blocks;
+ size_t next_long_name_blocks = 0;
+ size_t next_long_link_blocks = 0;
while (1)
{
/* Good block. Decode file size and return. */
if (header->header.typeflag == LNKTYPE)
- current_stat_info.stat.st_size = 0; /* links 0 size on tape */
+ info->stat.st_size = 0; /* links 0 size on tape */
else
- current_stat_info.stat.st_size = OFF_FROM_HEADER (header->header.size);
+ info->stat.st_size = OFF_FROM_HEADER (header->header.size);
if (header->header.typeflag == GNUTYPE_LONGNAME
|| header->header.typeflag == GNUTYPE_LONGLINK
else if (header->header.typeflag == GNUTYPE_LONGNAME
|| header->header.typeflag == GNUTYPE_LONGLINK)
{
- size_t name_size = current_stat_info.stat.st_size;
+ size_t name_size = info->stat.st_size;
size_t n = name_size % BLOCKSIZE;
size = name_size + BLOCKSIZE;
if (n)
size += BLOCKSIZE - n;
- if (name_size != current_stat_info.stat.st_size
- || size < name_size)
+ if (name_size != info->stat.st_size || size < name_size)
xalloc_die ();
header_copy = xmalloc (size + 1);
}
else if (header->header.typeflag == XHDTYPE
|| header->header.typeflag == SOLARIS_XHDTYPE)
- xheader_read (header, OFF_FROM_HEADER (header->header.size));
+ xheader_read (&info->xhdr, header,
+ OFF_FROM_HEADER (header->header.size));
else if (header->header.typeflag == XGLTYPE)
{
- xheader_read (header, OFF_FROM_HEADER (header->header.size));
- xheader_decode_global ();
- xheader_destroy (&extended_header);
+ struct xheader xhdr;
+ memset (&xhdr, 0, sizeof xhdr);
+ xheader_read (&xhdr, header,
+ OFF_FROM_HEADER (header->header.size));
+ xheader_decode_global (&xhdr);
+ xheader_destroy (&xhdr);
}
/* Loop! */
recent_long_name = 0;
recent_long_name_blocks = 0;
}
- assign_string (¤t_stat_info.orig_file_name, name);
- assign_string (¤t_stat_info.file_name, name);
- current_stat_info.had_trailing_slash = strip_trailing_slashes (current_stat_info.file_name);
+ assign_string (&info->orig_file_name, name);
+ assign_string (&info->file_name, name);
+ info->had_trailing_slash = strip_trailing_slashes (info->file_name);
if (recent_long_link)
free (recent_long_link);
recent_long_link = 0;
recent_long_link_blocks = 0;
}
- assign_string (¤t_stat_info.link_name, name);
+ assign_string (&info->link_name, name);
return HEADER_SUCCESS;
}
}
}
+enum read_header
+read_header (bool raw_extended_headers)
+{
+ return read_header_primitive (raw_extended_headers, ¤t_stat_info);
+}
+
+static char *
+decode_xform (char *file_name, void *data)
+{
+ int type = *(int*)data;
+
+ switch (type)
+ {
+ case XFORM_SYMLINK:
+ /* FIXME: It is not quite clear how and to which extent are the symbolic
+ links subject to filename transformation. In the absence of another
+ solution, symbolic links are exempt from component stripping and
+ name suffix normalization, but subject to filename transformation
+ proper. */
+ return file_name;
+
+ case XFORM_LINK:
+ file_name = safer_name_suffix (file_name, true, absolute_names_option);
+ break;
+
+ case XFORM_REGFILE:
+ file_name = safer_name_suffix (file_name, false, absolute_names_option);
+ break;
+ }
+
+ if (strip_name_components)
+ {
+ size_t prefix_len = stripped_prefix_len (file_name,
+ strip_name_components);
+ if (prefix_len == (size_t) -1)
+ prefix_len = strlen (file_name);
+ file_name += prefix_len;
+ }
+ return file_name;
+}
+
+bool
+transform_member_name (char **pinput, int type)
+{
+ return transform_name_fp (pinput, type, decode_xform, &type);
+}
+
#define ISOCTAL(c) ((c)>='0'&&(c)<='7')
/* Decode things from a file HEADER block into STAT_INFO, also setting
&& ISOCTAL (header->star_header.ctime[0])
&& header->star_header.ctime[11] == ' ')
format = STAR_FORMAT;
- else if (extended_header.size)
+ else if (stat_info->xhdr.size)
format = POSIX_FORMAT;
else
format = USTAR_FORMAT;
|| stat_info->dumpdir)
stat_info->is_dumpdir = true;
}
+
+ transform_member_name (&stat_info->file_name, XFORM_REGFILE);
+ switch (header->header.typeflag)
+ {
+ case SYMTYPE:
+ transform_member_name (&stat_info->link_name, XFORM_SYMLINK);
+ break;
+
+ case LNKTYPE:
+ transform_member_name (&stat_info->link_name, XFORM_LINK);
+ }
}
/* Convert buffer at WHERE0 of size DIGS from external format to
char modes[11];
char const *time_stamp;
int time_stamp_len;
- char *temp_name = st->orig_file_name ? st->orig_file_name : st->file_name;
+ char *temp_name;
/* These hold formatted ints. */
char uform[UINTMAX_STRSIZE_BOUND], gform[UINTMAX_STRSIZE_BOUND];
if (test_label_option && current_header->header.typeflag != GNUTYPE_VOLHDR)
return;
- if (show_stored_names_option)
- {
- switch (subcommand_option)
- {
- case CAT_SUBCOMMAND:
- case UPDATE_SUBCOMMAND:
- case APPEND_SUBCOMMAND:
- case CREATE_SUBCOMMAND:
- temp_name = st->file_name ? st->file_name : st->orig_file_name;
- break;
-
- default:
- temp_name = st->orig_file_name ? st->orig_file_name : st->file_name;
- }
- }
+ if (show_transformed_names_option)
+ temp_name = st->file_name ? st->file_name : st->orig_file_name;
else
temp_name = st->orig_file_name ? st->orig_file_name : st->file_name;
modes[0] = 'M';
break;
- case GNUTYPE_NAMES:
- modes[0] = 'N';
- break;
-
case GNUTYPE_LONGNAME:
case GNUTYPE_LONGLINK:
modes[0] = 'L';
uintbuf));
fprintf (stdlis, _("--Continued at byte %s--\n"), size);
break;
-
- case GNUTYPE_NAMES:
- fprintf (stdlis, _("--Mangled file names--\n"));
- break;
}
}
fflush (stdlis);