]> Dogcows Code - chaz/tar/blobdiff - src/list.c
Relicense under GPLv3
[chaz/tar] / src / list.c
index 4bf302e6d629fbc57726ea9ac071483c009ad3a5..c9cdf8246fbf2134f7846aacc4ea91ee9532f195 100644 (file)
@@ -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 (&current_stat_info);
-      xheader_destroy (&extended_header);
 
       status = read_header (false);
       switch (status)
@@ -387,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!  */
@@ -467,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,
@@ -481,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
@@ -510,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;
@@ -599,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
This page took 0.022046 seconds and 4 git commands to generate.