X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Flist.c;h=b17f604303f60dac99f8c14f14338d0cf0091f82;hb=b893aee6d22f11d234157d4bf8deb1b7ad53680e;hp=33c1d533ef95577817b4451bb8ca7c51f6bd3046;hpb=ae7bd36423b55af53703069fde93e396fc262c7d;p=chaz%2Ftar diff --git a/src/list.c b/src/list.c index 33c1d53..b17f604 100644 --- a/src/list.c +++ b/src/list.c @@ -1,13 +1,13 @@ /* 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 @@ -76,7 +76,6 @@ read_and (void (*do_something) (void)) { prev_status = status; tar_stat_destroy (¤t_stat_info); - xheader_destroy (&extended_header); status = read_header (false); switch (status) @@ -107,7 +106,6 @@ read_and (void (*do_something) (void)) { case GNUTYPE_VOLHDR: case GNUTYPE_MULTIVOL: - case GNUTYPE_NAMES: break; case DIRTYPE: @@ -303,8 +301,8 @@ read_header_primitive (bool raw_extended_headers, struct tar_stat_info *info) 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) { @@ -388,12 +386,16 @@ read_header_primitive (bool raw_extended_headers, struct tar_stat_info *info) } 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! */ @@ -468,9 +470,29 @@ read_header (bool raw_extended_headers) } static char * -decode_xform (char *file_name) +decode_xform (char *file_name, void *data) { - file_name = safer_name_suffix (file_name, false, absolute_names_option); + xform_type type = *(xform_type*)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, @@ -482,6 +504,12 @@ decode_xform (char *file_name) return file_name; } +bool +transform_member_name (char **pinput, xform_type type) +{ + return transform_name_fp (pinput, decode_xform, &type); +} + #define ISOCTAL(c) ((c)>='0'&&(c)<='7') /* Decode things from a file HEADER block into STAT_INFO, also setting @@ -511,7 +539,7 @@ decode_header (union block *header, struct tar_stat_info *stat_info, && 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; @@ -600,7 +628,7 @@ decode_header (union block *header, struct tar_stat_info *stat_info, stat_info->is_dumpdir = true; } - transform_name_fp (&stat_info->file_name, decode_xform); + transform_member_name (&stat_info->file_name, xform_regfile); } /* Convert buffer at WHERE0 of size DIGS from external format to @@ -1047,10 +1075,6 @@ print_header (struct tar_stat_info *st, off_t block_ordinal) modes[0] = 'M'; break; - case GNUTYPE_NAMES: - modes[0] = 'N'; - break; - case GNUTYPE_LONGNAME: case GNUTYPE_LONGLINK: modes[0] = 'L'; @@ -1234,10 +1258,6 @@ print_header (struct tar_stat_info *st, off_t block_ordinal) uintbuf)); fprintf (stdlis, _("--Continued at byte %s--\n"), size); break; - - case GNUTYPE_NAMES: - fprintf (stdlis, _("--Mangled file names--\n")); - break; } } fflush (stdlis);